Sign In with Apple is a new service, created by Apple, to allow users to use a secure login which won’t take off their privacy.

Sign In with Apple is available for iOS 13, tvOS 13, watchOS 6 and macOS Catalina. Besides that, the service is also available for Javascript using a simple API. The API can be used on the web and even supports Touch ID on MacOS.

Using the API, it is possible to get the full name and email from a user. Apple made a secure way to allow users to share their email, without sharing their real email. Users can select the option to use a forwarder, instead of their real email, so they are able to block that email as soon as they think your app is sending spam.

Setup the AuthenticationServices API entitlement

Implementing the new login service from Apple can be done with the AuthenticationServices API. Before you’re able to use the API, you need to add the ‘Sign In with Apple’ entitlement to the project.

In Xcode, navigate to your targets and select the target (app) which you want to provide Sign In with Apple. Go to the tab ‘Signing & Capabilities’ in the menu, and press the + button to add ‘Sign In with Apple’ to your project.

You’re now able to use the AuthenticationServices API in your code.

Add the sign in button in your view

There are multiple ways to implement the login button in your app. The class name for the login button is ASAuthorizationAppleIDButton. You can add the button by code or by dragging a UIButton to your storyboard and override the class with ASAuthorizationAppleIDButton.

When a user press on the sign in button, it must trigger the authorization flow. This can be done by adding the following code:

@objc func handleAuthorizationAppleID() {
    let request = ASAuthorizationAppleIDProvider().createRequest()
    
    request.requestedScopes = [.fullName, .email]
    
    let controller = ASAuthorizationController(authorizationRequests: [request])
    
    controller.delegate = self
    controller.presentationContextProvider = self
    
    controller.performRequests()
}

The code above is creating a request for authorization. The request will ask for the full name of the user and the email.

Then, an ASAuthorizationController will be initialized with the request just created. We also need to set the delegate of the ASAuthorizationController to receive the finish state or an error state. The presentationContextProvider is needed to return the current view where the ASAuthorizationController can be displayed on.

When everything is set, we can ask the ASAuthorizationController to perform the request. As soon as a user press the button, the ‘Sign In with Apple’ flow will be displayed to your user.

ASAuthorizationControllerDelegate

As soon as the user interacts with the ASAuthorizationController, the delegate can get two different states: success or an error.

didCompleteWithAuthorization

The didCompleteWithAuthorization delegate function will be triggered as soon as the authorization did finish. You will have an ASAuthorization object inside this delegate, which contains the credential and the provider.

The credentials will contain the data requested by the user. When using the above code example, the credentials will contain both the fullName and the email of the user. Only request those data from Apple if you need this in the app, otherwise, don’t ask for this personal data.

The credential object not only contains the name and email of the user, but also the user identifier, which is a unique ID that represents the user. This may be needed when you want to login a user who already has an existing account and you want to connect those accounts.

Code example:

func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
    guard let appleIDCredentials = authorization.credential as? ASAuthorizationAppleIDCredential else { return }
    
    let userIdentifier = appleIDCredentials.user
    let fullName = appleIDCredentials.fullName
    let email = appleIDCredentials.email
}

didCompleteWithError

If the authorization did fail for some reason, the didCompleteWithError delegate will be triggered. This delegate contains an Error object, which contains the error reason.

Multiple errors can happen on authorize. One of the most happened errors will be the ASAuthorizationErrorCanceled, which is triggered as soon as the user cancels the authorization. You may not want to trigger an error alert for each error, because a cancel action may be a conscious choice.

ASAuthorizationController PresentationContextProviding

To allow the ASAuthorizationController to be displayed in your view, a view should be assigned to present the controller. This can be done using the ASAuthorizationControllerPresentationContextProviding.

It only contains one function, named presentationAnchor(for controller: ASAuthorizationController). In this function, the window should be returned which is currently used, so the controller can become visible on that view.

Code example:

extension LoginViewController: ASAuthorizationControllerPresentationContextProviding {
    func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
        return self.view.window!
    }
}

Required when offering third-party sign in

Are you currently using third-party sign-in services in your apps using Facebook, Google, Twitter or any other third-party? In that case, you need to implement ‘Sign In with Apple’, because of the new App Store guidelines. These guidelines describe that a user must get the option to sign in with the new service from Apple.

Apps that exclusively use a third-party or social login service (such as Facebook Login, Google Sign-In, Sign in with Twitter, Sign In with Linked-In, Login with Amazon, or WeChat Login) to set up or authenticate the user’s primary account with the app must also offer Sign in with Apple as an equivalent option. A user’s primary account is the account they establish with your app for the purposes of identifying themselves, signing in, and accessing your features and associated services.

Apple. Source: developer.apple.com

🚀 Like this article? Follow me on Twitter for more iOS related news!