I am trying to implement a web authentication service in my app however, when I try to put webAuthSession.presentationContextProvider = self
, I get an error saying Cannot find 'self' in scope. All the turorials I have followed did the same thing without any errors. I am truly desperate so any help would be appreciated.
Thank you very much in advance!
import Foundation
import AuthenticationServices
import CryptoKit
typealias ASPresentationAnchor = UIWindow
class SignInViewModel: NSObject, ObservableObject, ASWebAuthenticationPresentationContextProviding {
func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
return ASPresentationAnchor()
}
}
public func UrlGenerator() -> URL {
func randomString(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<length).map{ _ in letters.randomElement()! })
}
let code_verifier = randomString(length: 86)
let hashdata = Data(code_verifier.utf8)
let code_challenge_data = SHA256.hash(data: hashdata)
let code_challenge_generated = code_challenge_data.compactMap { String(format: "x", $0) }.joined()
let url = "auth.tesla.com/oauth2/v3/authorize"
let client_id = "ownerapi"
let code_challenge = "\(code_challenge_generated)"
let code_challenge_method = "S256"
let redirect_uri = "https://auth.tesla.com/void/callback"
let response_type = "code"
let scope = "openid email offline_access"
let state = "\(code_verifier)"
let TeslaLink = "\(url)?client_id=\(client_id)&code_challenge=\(code_challenge)&code_challenge_method=\(code_challenge_method)&redirect_uri=\(redirect_uri)&response_type=\(response_type)&scope=\(scope)&state=\(state)"
let TeslaLinkURL = URL(string: TeslaLink)!
return TeslaLinkURL
}
let webAuthSession = ASWebAuthenticationSession.init(
url: UrlGenerator(),
callbackURLScheme: "TESRIUM",
completionHandler: { (callback:URL?, error:Error?) in
})
public func TeslaSignIn() {
webAuthSession.presentationContextProvider = self
webAuthSession.prefersEphemeralWebBrowserSession = false
webAuthSession.start()
}
CodePudding user response:
To answer your question, the reason self
is not available is because you're referring to it in the global context and self
has no meaning in the global context. self
must refer to an object and self
in the global scope is an environment, not an object.
The reason your specific code doesn't work is because you've separated the instantiation of webAuthSession
from the work you perform on it. In the tutorial, webAuthSession = ASWebAuthenticationSession.init...
and webAuthSession?.presentationContextProvider = self
are in the same scope. Therefore, simply merge them together into the same function. Now, where that function is also matters because if it's a global function you'll have the same problem. You need to place this function into the right object so self
is referring to what it's supposed to refer to.
public func TeslaSignIn() {
let webAuthSession = ASWebAuthenticationSession.init(
url: UrlGenerator(),
callbackURLScheme: "TESRIUM",
completionHandler: { (callback:URL?, error:Error?) in
})
webAuthSession.presentationContextProvider = self
webAuthSession.prefersEphemeralWebBrowserSession = false
webAuthSession.start()
}