Platform
Sign Up With Apple
15 min
sign in with apple tutorial introduction sign in with apple enables users to sign in to apps using their apple id this feature is available on ios 13 and later, and parse 3 5 and later prerequisites to complete this tutorial, you will need an app created at back4app see the create new app tutorial to learn how to create an app at back4app set up a subdomain for your back4app app see activating your web hosting and live query to learn how to create a subdomain in back4app an apple developer account 1 create a new back4app app first of all, it’s necessary to make sure that you have an existing app created at back4app however, if you are a new user, you can check this tutorial https //www back4app com/docs/get started/new parse app to learn how to create one 2 add the sign in with apple capability to your xcode project in your xcode project, click on the target (1) and go to the signing & capabilities tab (2) click the + capability + capability button (3) and add the sign in with apple sign in with apple capability (4) while there, choose your bundle identifier bundle identifier (5) and hold that information because we will need it later 3 create a new service id log into your apple developer account https //developer apple com/ and go to the identifiers identifiers section check if your created bundle identifier bundle identifier is there click the bundle identifier bundle identifier and scroll down check if the sign in with apple sign in with apple is selected click edit edit and make sure the enable as a primary app id enable as a primary app id is selected if everything is right, save and exit 4 set up parse auth for apple go to the back4app website, log in, and then find your app after that, click on server settings server settings search for the apple login apple login block, and select settings settings the apple login apple login section looks like this now, you just need to paste your bundle id bundle id in the field below and click on the button to save in case you face any trouble while integrating apple login, please contact our team via chat! 5 option 1 download our template there is some coding involved in making sign in with apple work, so we created this template https //github com/templates back4app/parsesigninwithapple that you can download, and change the bundle identifier bundle identifier , the app id app id , and client key client key the code is fully documented so it is a good starting point if you prefer to read through this doc, please go on to the next step 6 option 2 manually write code inside your view, add the authenticationservices framework and create the authdelegate that will handle the pfuserauthenticationdelegate 1 import authenticationservices 2 3 class authdelegate\ nsobject, pfuserauthenticationdelegate { 4 func restoreauthentication(withauthdata authdata \[string string]?) > bool { 5 return true 6 } 7 8 func restoreauthenticationwithauthdata(authdata \[string string]?) > bool { 9 return true 10 } 11 } 7 implement your delegates for the viewcontroller implement the asauthorizationcontrollerdelegate and asauthorizationcontrollerpresentationcontextproviding for the viewcontroller 1 class viewcontroller uiviewcontroller, asauthorizationcontrollerdelegate, asauthorizationcontrollerpresentationcontextproviding 8 add the sign in with apple button the viewdidappear is a good place for it if you choose other places, remember to call it just once 1 override func viewdidappear( animated bool) { 2 super viewdidappear(animated) 3 4 // sign in with apple button 5 let signinwithapplebutton = asauthorizationappleidbutton() 6 7 // set this so the button will use auto layout constraint 8 signinwithapplebutton translatesautoresizingmaskintoconstraints = false 9 10 // add the button to the view controller root view 11 self view\ addsubview(signinwithapplebutton) 12 13 // set constraint 14 nslayoutconstraint activate(\[ 15 signinwithapplebutton leadinganchor constraint(equalto view\ safearealayoutguide leadinganchor, constant 50 0), 16 signinwithapplebutton trailinganchor constraint(equalto view\ safearealayoutguide trailinganchor, constant 50 0), 17 signinwithapplebutton bottomanchor constraint(equalto view\ safearealayoutguide bottomanchor, constant 70 0), 18 signinwithapplebutton heightanchor constraint(equaltoconstant 50 0) 19 ]) 20 21 // the function that will be executed when user tap the button 22 signinwithapplebutton addtarget(self, action #selector(applesignintapped), for touchupinside) 23 } the applesignintapped in the last line must also be defined inside the viewcontroller class 1 // this is the function that will be executed when user taps the button 2 @objc func applesignintapped() { 3 let provider = asauthorizationappleidprovider() 4 let request = provider createrequest() 5 // request full name and email from the user's apple id 6 request requestedscopes = \[ fullname, email] 7 8 // pass the request to the initializer of the controller 9 let authcontroller = asauthorizationcontroller(authorizationrequests \[request]) 10 11 // similar to delegate, this will ask the view controller 12 // which window to present the asauthorizationcontroller 13 authcontroller presentationcontextprovider = self 14 15 // delegate functions will be called when user data is 16 // successfully retrieved or error occured 17 authcontroller delegate = self 18 19 // show the sign in with apple dialog 20 authcontroller performrequests() 21 } 9 the presentationcontextprovider the presentationcontextprovider (asauthorizationcontrollerpresentationcontextproviding) will ask for which window should display the authorization dialog as we are going to display it in the same window, we must return self view\ window 1 func presentationanchor(for controller asauthorizationcontroller) > aspresentationanchor { 2 // return the current view window 3 return self view\ window! 4 } 10 handling the delegate asauthorizationcontrollerdelegate there are a few options that we must handle when the delegate is called, so let’s add some code to handle those options distinctly 1 func authorizationcontroller(controller asauthorizationcontroller, didcompletewitherror error error) { 2 print("authorization error") 3 guard let error = error as? asauthorizationerror else { 4 return 5 } 6 7 switch error code { 8 case canceled 9 // user press "cancel" during the login prompt 10 print("canceled") 11 case unknown 12 // user didn't login their apple id on the device 13 print("unknown") 14 case invalidresponse 15 // invalid response received from the login 16 print("invalid respone") 17 case nothandled 18 // authorization request not handled, maybe internet failure during login 19 print("not handled") 20 case failed 21 // authorization failed 22 print("failed") 23 @unknown default 24 print("default") 25 } 26 } 11 handling the delegate for didcompletewithauthorization when we successfully authenticate, we can retrieve the authorized information 1 func authorizationcontroller(controller asauthorizationcontroller, didcompletewithauthorization authorization asauthorization) { 2 3 if let appleidcredential = authorization credential as? asauthorizationappleidcredential { 4 // unique id for each user, this uniqueid will always be returned 5 let userid = appleidcredential user 6 print("userid " + userid) 7 8 // if needed, save it to user defaults by uncommenting the line below 9 //userdefaults standard set(appleidcredential user, forkey "userid") 10 11 // optional, might be nil 12 let email = appleidcredential email 13 print("email " + (email ?? "no email") ) 14 15 // optional, might be nil 16 let givenname = appleidcredential fullname? givenname 17 print("given name " + (givenname ?? "no given name") ) 18 19 // optional, might be nil 20 let familyname = appleidcredential fullname? familyname 21 print("family name " + (familyname ?? "no family name") ) 22 23 // optional, might be nil 24 let nickname = appleidcredential fullname? nickname 25 print("nick name " + (nickname ?? "no nick name") ) 26 / 27 useful for server side, the app can send identitytoken and authorizationcode 28 to the server for verification purpose 29 / 30 var identitytoken string? 31 if let token = appleidcredential identitytoken { 32 identitytoken = string(bytes token, encoding utf8) 33 print("identity token " + (identitytoken ?? "no identity token")) 34 } 35 36 var authorizationcode string? 37 if let code = appleidcredential authorizationcode { 38 authorizationcode = string(bytes code, encoding utf8) 39 print("authorization code " + (authorizationcode ?? "no auth code") ) 40 } 41 42 // do what you want with the data here 43 44 } 45 } that’s the place where we can also add code for logging in parse so right after the do what you want with the data here do what you want with the data here comment, let’s add 1 pfuser loginwithauthtype(inbackground "apple", authdata \["token" string(identitytoken!), "id" userid]) continuewith { task > any? in 2 if ((task error) != nil){ 3 //dispatchqueue main async { 4 print("could not login \nplease try again ") 5 print("error with parse login after siwa \\(task error! localizeddescription)") 6 //} 7 return task 8 } 9 print("successfuly signed in with apple") 10 return nil 11 } and of course, add the parse framework 1 import parse