1.允許項目 appleID 登錄

swift
import UIKit import AuthenticationServices /// AppleId 登錄 class TGSAppleIdManager: NSObject{ static let share = TGSAppleIdManager() /// 失敗回調 private var failureHandle:((_ errtip: String)->Void)? /// 成功回調 private var sucessHandle:(( _ identityToken: Data, _ authorizationCode: Data, _ user: String)->Void)? } extension TGSAppleIdManager{ /// 登錄蘋果ID /// - Parameters: /// - sucessHandle: 成功回調 /// - failureHandle: 失敗回調 func loginAppleId(sucessHandle:(( _ identityToken: Data, _ authorizationCode: Data, _ user: String)->Void)?, failureHandle:(( _ errtip: String)->Void)?){ if #available(iOS 13.0, *) { self.sucessHandle = sucessHandle self.failureHandle = failureHandle //基於用戶的Apple ID 授權用戶,生成用戶授權請求的一種機制 let appleIdProvider = ASAuthorizationAppleIDProvider() //創建新的Apple ID授權請求 let request = appleIdProvider.createRequest() //在用戶授權期間請求的聯系信息 request.requestedScopes = [ASAuthorization.Scope.email, ASAuthorization.Scope.fullName] //由ASAuthorizationAppleIDProvider創建的授權請求,管理授權請求的控制器 let controller = ASAuthorizationController.init(authorizationRequests: [request]) //設置授權控制器通知授權請求的成功與失敗的代理 controller.delegate = self; //提供展示上下文的代理,在這個上下文中,系統可以展示授權界面給用戶 controller.presentationContextProvider = self; controller.performRequests() } } //MARK:暫未測試 // // 如果存在iCloud Keychain 憑證或者AppleID 憑證提示用戶 // func perfomExistingAccountSetupFlows() { // // 基於用戶的Apple ID授權用戶,生成用戶授權請求的一種機制 // if #available(iOS 13.0, *) { // let appleIDProvide = ASAuthorizationAppleIDProvider() // // 授權請求AppleID // let request = appleIDProvide.createRequest() // // 為了執行鑰匙串憑證分享生成請求的一種機制 // let passwordProvider = ASAuthorizationPasswordProvider() // let passwordRequest = passwordProvider.createRequest() // // 由ASAuthorizationAppleIDProvider創建的授權請求 管理授權請求的控制器 // let controller = ASAuthorizationController.init(authorizationRequests: [request,passwordRequest]) // // 設置授權控制器通知授權請求的成功與失敗的代理 // controller.delegate = self // // 設置提供 展示上下文的代理,在這個上下文中 系統可以展示授權界面給用戶 // controller.presentationContextProvider = self // // 在控制器初始化期間啟動授權流 // controller.performRequests() // } // } // // private func loginWithServer(user:String,token:String,code:String) { // //向你的服務器驗證 ,驗證通過即可登錄 // } } //MARK: - 代理 ASAuthorizationControllerDelegate 處理數據回調 extension TGSAppleIdManager:ASAuthorizationControllerDelegate{ //授權成功地回調 @available(iOS 13.0, *) func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential{ let identityToken = appleIDCredential.identityToken ?? Data() let authorizationCode = appleIDCredential.authorizationCode ?? Data() let user = appleIDCredential.user sucessHandle?(identityToken, authorizationCode, user) // // 使用過授權的,可能獲取不到以下三個參數 // let familyName = appleIDCredential.fullName?.familyName ?? "" // let givenName = appleIDCredential.fullName?.givenName ?? "" // let email = appleIDCredential.email ?? "" // // 用於判斷當前登錄的蘋果賬號是否是一個真實用戶,取值有:unsupported、unknown、likelyReal // let realUserStatus = appleIDCredential.realUserStatus } //MARK:暫未測試 // else if let passworCreddential = authorization.credential as? ASPasswordCredential{ // // 這個獲取的是iCloud記錄的賬號密碼,需要輸入框支持iOS 12 記錄賬號密碼的新特性,如果不支持,可以忽略 // // Sign in using an existing iCloud Keychain credential. // // 用戶登錄使用現有的密碼憑證 // // 密碼憑證對象的用戶標識 用戶的唯一標識 // let user = passworCreddential.user // // 密碼憑證對象的密碼 // let password = passworCreddential.password // }else{ // // "授權信息不符合" // } } @available(iOS 13.0, *) func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) { var errorStr : String? switch (error as NSError).code { case ASAuthorizationError.canceled.rawValue : errorStr = "用戶取消了授權請求" case ASAuthorizationError.failed.rawValue : errorStr = "授權請求失敗" case ASAuthorizationError.invalidResponse.rawValue : errorStr = "授權請求無響應" case ASAuthorizationError.notHandled.rawValue : errorStr = "未能處理授權請求" case ASAuthorizationError.unknown.rawValue : errorStr = "授權請求失敗原因未知" default: break } if let _errorStr = errorStr { failureHandle?(_errorStr) } } } //MARK: - 代理 ASAuthorizationControllerPresentationContextProviding 管理視圖彈出在哪里 extension TGSAppleIdManager:ASAuthorizationControllerPresentationContextProviding{ @available(iOS 13.0, *) func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor { return TGSWindow } }
OC
.h 文件
#import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface AppleIDLoginTool : NSObject @property (strong, nonatomic) RACSubject *delegateSubject; - (void)loginWithAppleId; @end NS_ASSUME_NONNULL_END
.m文件
#import "AppleIDLoginTool.h" #import <AuthenticationServices/AuthenticationServices.h> @interface AppleIDLoginTool()<ASAuthorizationControllerDelegate,ASAuthorizationControllerPresentationContextProviding> @end @implementation AppleIDLoginTool - (void)loginWithAppleId { if (@available(iOS 13.0, *)) { //基於用戶的Apple ID 授權用戶,生成用戶授權請求的一種機制 ASAuthorizationAppleIDProvider *appleIdProvider = [[ASAuthorizationAppleIDProvider alloc] init]; //創建新的Apple ID授權請求 ASAuthorizationAppleIDRequest *request = appleIdProvider.createRequest; //在用戶授權期間請求的聯系信息 request.requestedScopes = @[ASAuthorizationScopeEmail,ASAuthorizationScopeFullName]; //由ASAuthorizationAppleIDProvider創建的授權請求,管理授權請求的控制器 ASAuthorizationController *controller = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]]; //設置授權控制器通知授權請求的成功與失敗的代理 controller.delegate = self; //提供展示上下文的代理,在這個上下文中,系統可以展示授權界面給用戶 controller.presentationContextProvider = self; [controller performRequests]; }else{ NSLog(@"system is lower"); } } #pragma mark - appleId登錄代理方法 //授權成功的方法 - (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)){ if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) { ASAuthorizationAppleIDCredential *credential = (ASAuthorizationAppleIDCredential *)authorization.credential; NSString *user = credential.user; NSData *identityToken = credential.identityToken; NSData *code = credential.authorizationCode; NSString *token = [[NSString alloc] initWithData:identityToken encoding:NSUTF8StringEncoding]; NSString *codeStr = [[NSString alloc] initWithData:code encoding:NSUTF8StringEncoding]; //授權成功后, 拿到返回的全部數據, 根據需要和后台交互 NSLog(@"user - %@ %@",user,identityToken); //保存apple返回的唯一標識符 [[NSUserDefaults standardUserDefaults] setObject:user forKey:@"userIdentifier"]; [[NSUserDefaults standardUserDefaults] synchronize]; if (self.delegateSubject) { [self.delegateSubject sendNext:@{@"appleId":user,@"identityToken":token,@"code":codeStr}]; } }else if ([authorization.credential isKindOfClass:[ASPasswordCredential class]]) { ASPasswordCredential *pdCredential = (ASPasswordCredential *)authorization.credential; // 密碼憑證對象的用戶標識 用戶的唯一標識 NSString *user = pdCredential.user; NSString *psd = pdCredential.password; NSLog(@"pduser - %@ %@",user,psd); }else{ NSLog(@"授權信息不符"); } } //授權失敗的方法 - (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)){ NSLog(@"錯誤信息 %@",error); NSString *errorMsg; switch (error.code) { case ASAuthorizationErrorCanceled: errorMsg = @"您取消了授權請求"; break; case ASAuthorizationErrorFailed: errorMsg = @"授權請求失敗"; break; case ASAuthorizationErrorInvalidResponse: errorMsg = @"授權請求無響應"; break; case ASAuthorizationErrorNotHandled: errorMsg = @"未能處理授權請求"; break; case ASAuthorizationErrorUnknown: errorMsg = @"授權請求發生未知原因錯誤"; break; default: break; } [HUDManager showTextHud:errorMsg]; NSLog(@"errorMsg - %@",errorMsg); } - (nonnull ASPresentationAnchor)presentationAnchorForAuthorizationController:(nonnull ASAuthorizationController *)controller API_AVAILABLE(ios(13.0)){ return [Adaptive_iOS_13_ToolUtil iOS13_keyWindow]; } @end
