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