iOS
...
Users
Sign In with Apple
12 min
sign in with apple introduction when integrating third party sign in methods on an ios app, it is mandatory to add the sign in with apple option as an additional alternative for this purpose, apple introduced the authenticationservices framework this framework allows developers to seamlessly integrate a sign in with apple button on any xcode project in this repository https //github com/templates back4app/ios sign in with apple we provide a simple xcode template where you can test the different sign in methods we are implementing this example was already introduced in the log in guide https //www back4app com/docs/ios/parse swift sdk/users/user log in you can revisit it for more details about the project prerequisites to complete this quickstart, you need a recent version of xcode an apple developer account with non personal developer team an app created at back4app follow the new parse app tutorial to learn how to create a parse app at back4app note follow the install parse sdk (swift) tutorial to create an xcode project connected to back4app goal to integrate a user sign in feature using the authenticationservices framework and parseswift sdk 1 setting up sign in with apple once we have the xcode project linked to the back4app application, we proceed to add the sign in with apple capability to do this, select your project from the project navigator and go to the targets section select the main target and go to the signing & capabilities tab, then click on the + capability button and add the sign in with apple capability this is the only configuration needed to start integrating a sign in with apple method on an ios app 2 using the authenticationservices framework with parseswift the sign in with apple flow can be completed in three stages but before, let us add and set up the button to be used to present the sign in with apple flow in the logincontroller logincontroller class we add this button 1 // logincontroller swift file 2 import authenticationservices 3 4 5 class logincontroller uiviewcontroller { 6 7 8 private let signinwithapplebutton uibutton = { 9 let button = uibutton(type system) 10 button setimage(uiimage(named "appleicon"), for normal) 11 button imageview? contentmode = scaleaspectfit 12 return button 13 }() 14 15 override func viewdidload() { 16 super viewdidload() 17 // 18 // layout configuration 19 // 20 21 signinwithapplebutton addtarget(self, action #selector(handlesigninwithapple), for touchupinside) 22 } 23 } 24 25 // mark sign in with apple section 26 extension logincontroller asauthorizationcontrollerdelegate, asauthorizationcontrollerpresentationcontextproviding { 27 @objc fileprivate func handlesigninwithapple() { 28 // todo here we will implement the sign in procedure 29 } 30 31 // asauthorizationcontrollerdelegate 32 33 func authorizationcontroller(controller asauthorizationcontroller, didcompletewithauthorization authorization asauthorization) { 34 // todo handle the sign in result 35 } 36 37 func authorizationcontroller(controller asauthorizationcontroller, didcompletewitherror error error) { 38 showmessage(title "error", message error localizeddescription) 39 } 40 41 // asauthorizationcontrollerpresentationcontextproviding 42 43 func presentationanchor(for controller asauthorizationcontroller) > aspresentationanchor { 44 guard let window = view\ window else { fatalerror("no uiwindow found!") } 45 return window 46 } 47 } note that the logincontroller logincontroller conforms to two new protocols asauthorizationcontrollerdelegate asauthorizationcontrollerdelegate and asauthorizationcontrollerpresentationcontextproviding asauthorizationcontrollerpresentationcontextproviding the first protocol allows us to delegate the sign in result to the logincontroller logincontroller class the second protocol is to determine the uiwindow uiwindow where the sign in sheet is displayed we now implement the flow in the handlesigninwithapple() handlesigninwithapple() method in the first stage, we prepare the request and the form the request is constructed by the asauthorizationappleidrequest asauthorizationappleidrequest class we get an instance of this class from the asauthorizationappleidprovider asauthorizationappleidprovider provider and the form by the asauthorizationcontrolle asauthorizationcontrolle r class once we have an instance of the request, we have to provide the scopes we are interested in so far apple only gives access to the user’s full name and email thus, a standard way to create a request is 1 @objc fileprivate func handlesigninwithapple() { 2 let provider = asauthorizationappleidprovider() 3 let request asauthorizationappleidrequest = provider createrequest() 4 request requestedscopes = \[ fullname, email] 5 6 } with this request, we construct an asauthorizationcontroller asauthorizationcontroller controller this controller is in charge of displaying a sheet where the user authenticates and gives the corresponding permissions to complete the sign in process 1 @objc fileprivate func handlesigninwithapple() { 2 // as requested by apple, we set up the necessary objects to implement the sign in with apple flow 3 // see https //help apple com/developer account/#/devde676e696 for more details 4 let provider = asauthorizationappleidprovider() 5 let request asauthorizationappleidrequest = provider createrequest() 6 request requestedscopes = \[ fullname, email] 7 8 let authorizationcontroller = asauthorizationcontroller(authorizationrequests \[request]) 9 authorizationcontroller delegate = self // here self is a reference to logincontroller 10 authorizationcontroller presentationcontextprovider = self // here self is a reference to logincontroller 11 12 // presents the sign in with apple sheet and the result will be handled by the asauthorizationcontrollerdelegate delegate 13 authorizationcontroller performrequests() 14 } in the last stage we handle the sign in result this is returned via the delegate method authorizationcontroller(controller\ didcompletewithauthorization ) authorizationcontroller(controller\ didcompletewithauthorization ) the last argument in this method is an asauthorization asauthorization class containing all the necessary information about the apple id and credentials this stage is where we associate a user user object and perform the log in to the back4app back4app application this user user object has the following structure (see the login guide for more details) 1 import parseswift 2 3 struct user parseuser { 4 5 6 var username string? 7 var email string? 8 var emailverified bool? 9 var password string? 10 11 var age int? 12 } now, we create a user user object from the data contained in the asauthorization asauthorization result we accomplish this by instantiating a parseapple parseapple object (from user apple user apple ) and call the login(user\ identitytoken ) login(user\ identitytoken ) method 1 // mark sign in with apple section 2 extension logincontroller asauthorizationcontrollerdelegate, asauthorizationcontrollerpresentationcontextproviding { 3 4 // asauthorizationcontrollerdelegate 5 6 func authorizationcontroller(controller asauthorizationcontroller, didcompletewithauthorization authorization asauthorization) { 7 // we cast the (asauthorization) authorization object to an asauthorizationappleidcredential object 8 guard let credential = authorization credential as? asauthorizationappleidcredential else { 9 return showmessage(title "sign in with apple", message "invalid credential") 10 } 11 12 guard let identitytoken = credential identitytoken else { 13 return showmessage(title "sign in with apple", message "token not found") 14 } 15 16 // we log in the user with the token generated by apple 17 user apple login(user credential user, identitytoken identitytoken) { \[weak self] result in 18 switch result { 19 case success(let user) 20 // after the login succeeded, we send the user to the home screen 21 // additionally, you can complete the user information with the data provided by apple 22 let homecontroller = homecontroller() 23 homecontroller user = user 24 25 self? navigationcontroller? pushviewcontroller(homecontroller, animated true) 26 case failure(let error) 27 self? showmessage(title "error", message error message) 28 } 29 } 30 } 31 } 3 verifying user sign in and session creation to make sure that the google sign in worked, you can look at your back4app application dashboard and see the new user user containing the facebook authdata authdata parameters you can also verify that a valid session was created in the dashboard, containing a pointer to the corresponding user user object 4 linking an existing user to an apple id in case your ios app requires relating an apple id to an existing user in your back4app platform, the parseapple\<user> parseapple\<user> object implements the method link(user\ identitytoken\ completion ) link(user\ identitytoken\ completion ) where you pass the user user value and the identitytoken identitytoken from a asauthorizationappleidcredential asauthorizationappleidcredential credential 1 let credential asauthorizationappleidcredential 2 3 guard let identitytoken = credentials identitytoken else { 4 return showmessage(title "sign in with apple", message "token not found") 5 } 6 7 user apple link(user credential user, identitytoken identitytoken){ result in 8 switch result { 9 case success(let user) 10 // linking succeeded, user object now is linked to the corresponding apple id 11 case failure(let error) 12 // linking failed, handle the error 13 } 14 } 5 run the app you can go to this repository and download the example project before running the project, make sure you set up the provisioning profiles with the ones associated with your developer account conclusion at the end of this guide, you learned how to sign in or link existing back4app users on ios using the sign in with apple