在iOS13中,如果蘋果開發者提供任何其他第三方登錄,就必須提供“蘋果登錄”選項。也就是說,如果軟件要求“微信登錄”或是“QQ登錄”時,必須同時提供“蘋果登錄”的選項給用戶自行選擇。根據蘋果公司最新公佈的指南,要求開發者在蘋果終端的應用程序登錄界面上,將“蘋果登錄”選項列在任何其他第三方登錄的選項之上。
注:以下內容源於官方文檔翻譯Sign in with Apple
1、添加登錄按鈕
func setupProviderLoginView() { let authorizationButton = ASAuthorizationAppleIDButton() authorizationButton.addTarget(self, action: #selector(handleAuthorizationAppleIDButtonPress), for: .touchUpInside) self.loginProviderStackView.addArrangedSubview(authorizationButton) }
提示:當你在故事板中添加用蘋果按鈕登錄時,你還必須在Xcode的身份檢查器中將控件的類值設置爲ASAuthorizationAppleIDButton。
2、請求Apple ID授權
當用戶點擊Apple按鈕登錄時,視圖控制器調用handleAuthorizationAppleIDButtonPress()函數,該函數通過對用戶的全名和電子郵件地址執行授權請求來啓動身份驗證流程。然後,系統檢查用戶是否用設備上的Apple ID登錄。如果用戶沒有在系統級登錄,應用程序會顯示一個警告,指示用戶在設置中使用他們的Apple ID登錄。
@objc func handleAuthorizationAppleIDButtonPress() { let appleIDProvider = ASAuthorizationAppleIDProvider() let request = appleIDProvider.createRequest() request.requestedScopes = [.fullName, .email] let authorizationController = ASAuthorizationController(authorizationRequests: [request]) authorizationController.delegate = self authorizationController.presentationContextProvider = self authorizationController.performRequests() }
提示:用戶在使用“登錄與蘋果”(Sign in with Apple)時,必須啓用雙重身份驗證,這樣才能安全訪問該賬戶。
授權控制器調用presentationAnchor(for:)函數來從應用程序獲取窗口,在窗口中,它會以模態表單的形式向用戶顯示帶有蘋果內容的登錄。
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor { return self.view.window! }
如果用戶使用Apple ID在系統級登錄,則會出現描述使用Apple功能登錄的工作表,然後是另一個工作表,允許用戶編輯其帳戶中的信息。用戶可以編輯他們的第一個和最後一個名稱,選擇另一個電子郵件地址作爲他們的聯繫信息,並從應用程序隱藏他們的電子郵件地址。如果用戶選擇隱瞞自己的電子郵件地址從應用程序,蘋果會生成一個代理郵箱地址轉發郵件到用戶的私人電子郵件地址。最後,用戶輸入Apple ID的密碼,然後單擊Continue創建帳戶。
3、Handle User Credentials
如果驗證成功,授權控制器調用authorizationController(controller:didCompleteWithAuthorization:)委託函數,應用程序使用該函數在密鑰鏈中存儲用戶數據。
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { switch authorization.credential { case let appleIDCredential as ASAuthorizationAppleIDCredential: // Create an account in your system. let userIdentifier = appleIDCredential.user let fullName = appleIDCredential.fullName let email = appleIDCredential.email // For the purpose of this demo app, store the `userIdentifier` in the keychain. self.saveUserInKeychain(userIdentifier) // For the purpose of this demo app, show the Apple ID credential information in the `ResultViewController`. self.showResultViewController(userIdentifier: userIdentifier, fullName: fullName, email: email) case let passwordCredential as ASPasswordCredential: // Sign in using an existing iCloud Keychain credential. let username = passwordCredential.user let password = passwordCredential.password // For the purpose of this demo app, show the password credential as an alert. DispatchQueue.main.async { self.showPasswordCredentialAlert(username: username, password: password) } default: break } }
在你的實現中,ASAuthorizationControllerDelegate.authorizationController(controller:didCompleteWithAuthorization:)委託函數應該使用用戶標識符中包含的數據在你的系統中創建一個帳戶。
如果身份驗證失敗,授權控制器調用authorizationController(controller:didCompleteWithError:)委託函數來處理錯誤。
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) { // Handle error. }
一旦系統驗證了用戶,應用程序就會顯示ResultViewController,它會顯示框架請求的用戶信息,包括用戶提供的全名和電子郵件地址。視圖控制器還顯示一個Sign Out按鈕,並將用戶數據存儲在密鑰鏈中。當用戶點擊Sign Out按鈕時,應用程序從視圖控制器和密鑰鏈中刪除用戶信息,並將LoginViewController呈現給用戶。
4、要求現有的憑證
performexistingaccountsetupflows()函數的作用是:通過請求蘋果ID和iCloud密鑰鏈密碼來檢查用戶是否擁有現有的帳戶。類似於handleAuthorizationAppleIDButtonPress(),授權控制器設置它的表示內容提供程序和LoginViewController對象的委託。
func performExistingAccountSetupFlows() { // Prepare requests for both Apple ID and password providers. let requests = [ASAuthorizationAppleIDProvider().createRequest(), ASAuthorizationPasswordProvider().createRequest()] // Create an authorization controller with the given requests. let authorizationController = ASAuthorizationController(authorizationRequests: requests) authorizationController.delegate = self authorizationController.presentationContextProvider = self authorizationController.performRequests() }