Authentication for Your iOS Apps with Apple Sign-in and Atlas App Services
Rate this tutorial
Mobile device authentication serves as the crucial first line of defense against potential intruders who aim to exploit personal information, financial data, or private details. As our mobile phones store a wealth of sensitive information, it is imperative to prioritize security while developing apps that ensure user safety.
Apple sign-in is a powerful solution that places user privacy at the forefront by implementing private email relay functionality. This enables users to shield their email addresses, granting them greater control over their data. Combining this with Atlas App Services provides developers with a streamlined and secure authentication experience. It also simplifies app development, service integration, and data connectivity, eliminating operational overhead.
This sample application consists of an iOS app with a “Sign in with Apple” button, where when the user taps on it, it will prompt the authentication native sheet that will allow the user to choose to sign in to your app hiding or showing their email address. Once the sign-up process is completed, the sign-in process gets handled by the Authentication API by Apple.
Since this tutorial’s main focus is on the code implementation with Apple sign-in, a few previous steps are required for it.
First, in your Atlas App Services app, go to Data Access -> Authentication on the sidebar.
In the Authentication Providers section, enable the Apple provider when tapping on the Edit button. You’ll see a screen like the one in the screenshot below:
You will have now to fill the corresponding fields with the following information:
- Client ID: Enter your application’s Bundle ID for the App Services Client ID.
Click on the “Save Draft” button and your changes will be deployed.
This is a pretty simple UIKit project, where LoginViewController.swift will implement the authentication functionality of Apple sign-in, and if the authenticated user is valid, then a segue will transition to WelcomeViewController.swift.
On top of the view controller code, make sure that you import both the AuthenticationServices and RealmSwift frameworks so you have access to their methods. In your Storyboard, add a UIButton of type ASAuthorizationAppleIDButton to the LoginViewController and link it to its corresponding Swift file.
In the viewDidLoad() function of LoginViewController, we are going to call setupAppleSignInButton(), which is a private function that lays out the Apple sign-in button, provided by the AuthenticationServices API. Here is the code of the functionality.
The private function adds a target to the appleSignInButton and gives it a radius of 10 to its corners. The screenshot below shows how the button is laid out in the testing device.
Now, moving to handleAppleIdRequest, here is the implementation for it:
This function is a method that handles the initialization of Apple ID authorization using ASAuthorizationAppleIDProvider and ASAuthorizationController classes. Here is a breakdown of what the function does:
- It creates an instance of ASAuthorizationAppleIDProvider, which is responsible for generating requests to authenticate users based on their Apple ID.
- Using the appleIDProvider instance, it creates an authorization request when calling createRequest().
- The request is used to configure the specific data that the app needs to access from the user’s Apple ID. In this case, we are requesting fullName and email.
- We create an instance of ASAuthorizationController that will manage the authorization requests and will also handle any user interactions related to the Apple ID authentication.
- The authorizationController has to set its delegate to self, as the current object will have to conform to the ASAuthorizationControllerDelegate protocol.
- Finally, the specified authorization flows are performed by calling performRequests(). This method triggers the system to present the Apple ID login interface to the user.
As we just mentioned, the view controller has to conform to the ASAuthorizationControllerDelegate. To do that, I created an extension of LoginViewController, where the implementation of the didCompleteWithAuthorization delegate method is where we will handle the successful authentication with the Swift Realm SDK.
To resume it in a few lines, this code retrieves the necessary user information from the Apple ID credential if the credentials of the user are successful. We also obtain the identityToken, which is the vital piece of information that is needed to use it on the Atlas App Services authentication.
However, note that this token has to be decoded in order to be used on Atlas App Services, and for that, you can use the String(decoding:, as:) method.
Once the token is decoded, it is a JWT that contains claims about the user signed by Apple Authentication Service. Then the realmSignIn() private method is called and the decoded token is passed as a parameter so the authentication can be handled.
The realmSignIn() private function handles the login into Atlas App Services. This function will allow you to authenticate your users that will be connected to your app without any additional hassle. First, the credentials are generated by Credentials.apple(idToken:), where the decoded Apple token is passed as a parameter.
If the login is successful, then the code performs a segue and goes to the main screen of the project, WelcomeViewController. If it fails, then it will print an error message. Of course, feel free to adapt this error to whatever suits you better for your use case (i.e., an alert message).
Another interesting delegate method in terms of error handling is the didCompleteWithError() delegate function, which will get triggered if there is an error during the Apple ID authentication. You can use this one to provide some feedback to the user and improve the UX of your application.
One of the biggest perks of Apple sign-in authentication, as it was mentioned earlier, is the flexibility it gives to the user regarding what gets shared with your app. This means that if the user decides to hide their email address and not to share their full name as the code was requested earlier through the requestedScopes definition, you will receive an empty string in the response. In the case of the email address, it will be a nil value.
I hope you found this tutorial helpful. I encourage you to explore our to discover all the benefits that it can offer to you when building iOS apps. We have plenty of resources available to help you learn and implement these features. So go ahead, dive in, and see what Atlas App Services has in store for your app development journey.