ASAuthorizationController delegate inside class not called

I have a class where I want to handle the Sign in with Apple logic. I have created an ASAuthorizationController, set the presentationContextProvider to be my view controller and set the delegate to the class itself. When I perform the requests, the system dialog shows up. But upon canceling, my delegate method does not get called.

Here is my class:


final class AppleSignInProvider: NSObject {
    typealias CompletionHandler = (Result<AuthCredential, Error>) -> Void

    enum AuthError: LocalizedError {
        case credential
        case nonce
        case identityToken
        case identityTokenString
    }

    private let completion: CompletionHandler
    private var authorizationController: ASAuthorizationController?

    init(completion: @escaping CompletionHandler) {
        self.completion = completion
    }

    private var currentNonce: String?

    private func sha256(nonce: String) -> String {
        let inputData = Data(nonce.utf8)
        let hashedData = SHA256.hash(data: inputData)
        let hashString = hashedData.compactMap {
            return String(format: "%02x", $0)
        }.joined()

        return hashString
    }

    func signIn(viewController: UIViewController) {
        let nonce = randomNonceString()
        currentNonce = nonce

        let request = ASAuthorizationAppleIDProvider().createRequest()
        request.requestedScopes = [
            .fullName, .email
        ]
        request.nonce = sha256(nonce: nonce)

        let authorizationController = ASAuthorizationController(authorizationRequests: [request])
        authorizationController.presentationContextProvider = viewController.view.window
        authorizationController.delegate = self
        authorizationController.performRequests()

        self.authorizationController = authorizationController
    }

    // Adapted from https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce
    private func randomNonceString(length: Int = 32) -> String {
        precondition(length > 0)
        let charset: [Character] = Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._")
        var result = ""
        var remainingLength = length

        while remainingLength > 0 {
            let randoms: [UInt8] = (0 ..< 16).map { _ in
                var random: UInt8 = 0
                let errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random)

                guard errorCode == errSecSuccess else {
                    fatalError("Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)")
                }

                return random
            }

            randoms.forEach { random in
                if remainingLength == 0 {
                    return
                }

                if random < charset.count {
                    result.append(charset[Int(random)])
                    remainingLength -= 1
                }
            }
        }

        return result
    }
}

extension AppleSignInProvider: ASAuthorizationControllerDelegate {
    func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        do {
            guard let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential else {
                throw AuthError.credential
            }

            guard let nonce = currentNonce else {
                throw AuthError.nonce
            }

            guard let appleIDToken = appleIDCredential.identityToken else {
                throw AuthError.identityToken
            }

            guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
                throw AuthError.identityTokenString
            }

            let credential = OAuthProvider.credential(withProviderID: "apple.com", idToken: idTokenString, rawNonce: nonce)
            completion(.success(credential))

        } catch {
            completion(.failure(error))
        }
    }

    func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
        completion(.failure(error))
    }
}

My delegate methods are called when the view controller is set as delegate, but that is not a fix for my issue.

Nevermind, it was a weak referencing issue.

I also encountered the same problem. Finally solved. presentationAnchor. It does not call, but it does not affect the process. Added a request. ASAuthorizationPasswordProvider().createRequest() There will be no animation bugs

 let appleIDProvider = ASAuthorizationAppleIDProvider()
 let request = appleIDProvider.createRequest()
 request.requestedScopes = [.fullName, .email]
      
 let authorizationController = ASAuthorizationController(authorizationRequests: [request, ASAuthorizationPasswordProvider().createRequest()])

For my case, i am using it with NFC and somehow the security key is not detected or there are some NFC hardware issues. The callback is not triggered until timeout. Any idea on NFC troubleshooting?

ASAuthorizationController delegate inside class not called
 
 
Q