On September 12 Apple updated their requirements and guidelines for SiWA which requires app developers to integrate sign in with Apple for apps that already have a sign in mechanism of sort like Facebook, Google etc..
The benefits of using SiWA :
- Our customers can safely use their Apple ID to log in into our app.
- It comes with a two-factor authentication.
- It has an anti-fraud mechanism.
- We get a verified email address.
- It is cross-platform.
Overview
Integrating Apple Sign-in into our app has four major steps which we will be covering the first three in this tutorial.
- Adding the UI
- Authorization
- Verification
- Handling changes
Protocol Oriented Programming
Instead of writing all the Sign-In code into a UIViewController I decided to use Protocol Oriented Programming to implement this feature.
It will allow us a more generic approach and one that can be reused for different projects with ease and elegance.
Protocol Oriented programming isn't new to Swift, in fact it is built into its core.
Let’s take for example the Array type, which inherits from several protocols like Comparable, Equatable, Collection etc..
It lets us build and separate logic while maintaining a higher level of abstraction which will naturally make your code easier to design and maintain over time.
If you’re interested in learning more about Protocol Oriented Programming I suggest you start with the WWDC 2015 Session by Dave Abrahams. I found it to be amusing and highly informative.
OK now that we have a bit more info regarding the steps for integrating the SiWA and know which design pattern we will use, let’s write some code.
Open Xcode 11 and create a new single view application (tick the storyboard checkbox option as we need a regular UIKit app template).
Go to your project target and click the Capability button, Search for sign in to add this option.
Create a new file and name it User.
This file will represent our ASAuthorizationAppleIDCredential in one object. It consists of an ID first and last name, as well as the user’s email.
The CustomDebugStringConvertible protocol will allow us a debugging textual representation when we use logs on our User type. Yet another protocol (:
Apple Sign in Protocol
Create a new file and name it AppleSigninProtocol.
We start by importing the AuthenticationServices framework which allows us to use Apple Sign In.
Then we use HandleAppleSignInDelegate as a selector, we call handleAuthorizationButtonPress( ) for when the Sign in button is tapped. This is due to the inability of an extension to populate an @objc method.
We then create our AppleSignIn Interface which conforms to two other interfaces which are ASAuthorizationControllerDelegate and ASAuthorizationControllerPresentationContextProviding.
ASAuthorization controller delegate provides information about the outcome of an authorization request.
ASAuthorization controller presentation context providing, provides an interface which the controller uses to ask a delegate for a presentation context, basically our main view.
Our AppleSignIn interface will implement two functions which is addAppleSignIn(delegate: HandleAppleSignInDelegate) and didTapAppleButton( ), addAppleSignIn takes one parameter which will be the controller using it.
Apple Sign In Interface Extension
We extend our AppleSignIn interface to work only with UIViewControllers types, this is a restriction, or more of a safety constraint.
The AppleSignin extension holds the default implementation for both addAppleSignIn and didTapAppleButton.
We then create our Apple Button using the (ASAuthorizationAppleIDButton) and add it to our view using programmatic constraints.
We use a provider to create a request (ASAuthorizationAppleIDRequest), which we then use to initialize a controller (ASAuthorizationController) that performs the request.
Upon success of the request, the controller’s delegate receives an authorization (ASAuthorization) containing a credential (ASAuthorizationAppleIDCredential) that has an opaque user identifier.
We will be using this credential to create our User object in the delegate method and print out the sign-in status in the Xcode console.
Create a new file and name it AppleSignInViewController and add the following code:
Go over AppleSIgnInViewController, I’m sure you will find it pretty straight forward, I added a label to the view and configure it with some constraints.
The most interesting part here is in viewDidLoad, where I call to addAppleSignIn(delegate: self). This Line will trigger the whole process and present the Apple Sign in controller. I found it magical 🎩🧚♀️
Apple Sign In ViewController Extension
We extend AppleSignInViewController and conform to AppleSignInInterface.
Here we will add the required ASAuthorizationControllerDelegate and ASAuthorizationControllerPresentationContextProviding delegate methods.
The first method didCompleteAuthorization gets called when the authorization request has succeeded fetching the users credentials.
The second method didCompleteWithError is called when the request has failed.
Lastly presentationAnchor returns the window on which the authorization controller should present on.