如果你的应用接入了第三方登陆,那么请同时接入苹果登录。
苹果审核指南的相关内容 新闻:2020年4月前需要适配好苹果登录
简单接入 苹果登录官方文档
流程:
用户点击按钮 — 调起苹果登录 — 授权成功 — 获取唯一标识符和其他信息 — 返回给后端 — 后端注册/登录 — 返回token — 登录成功
必要的工作
首先去苹果后台开启Sign in with apple
选项,然后重新导出provisionprofile
证书
授权
1 2 3 4 5 6 7 8 9 10 11 12 ASAuthorizationAppleIDProvider *provider = [[ASAuthorizationAppleIDProvider alloc] init]; ASAuthorizationAppleIDRequest *request = [provider createRequest]; request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail]; NSMutableArray <ASAuthorizationRequest *>* array = [NSMutableArray arrayWithCapacity:2]; if (request) [array addObject:request]; NSArray<ASAuthorizationRequest *> *requests = [array copy]; ASAuthorizationController *authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:requests]; authorizationController.delegate = self; authorizationController.presentationContextProvider = input; [authorizationController performRequests];
回调,遵循回调ASAuthorizationControllerPresentationContextProviding
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 - (void )authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0 )) { if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class ]]) { ASAuthorizationAppleIDCredential *appleIDCredential = (ASAuthorizationAppleIDCredential *)authorization.credential; NSString *user = appleIDCredential.user; NSString *namePerfix = appleIDCredential.fullName.namePrefix; NSString *givenName = appleIDCredential.fullName.givenName; NSString *middleName = appleIDCredential.fullName.middleName; NSString *familyName = appleIDCredential.fullName.familyName; NSString *nameSuffix = appleIDCredential.fullName.nameSuffix; NSString *email = appleIDCredential.email; NSString *nickname = appleIDCredential.fullName.nickname; if (!nickname || nickname.length == 0 ) { nickname = [NSString stringWithFormat:@"%@%@%@%@%@" ,namePerfix?:@"" ,familyName?:@"" ,givenName?:@"" ,middleName?:@"" ,nameSuffix?:@"" ]; } } else { [self .errorSubject sendNext:LMError(@"授权信息有误" )]; } } - (void )authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0 )) { NSString *errorMsg = nil ;switch (error.code) { case ASAuthorizationErrorCanceled: errorMsg = @"用户取消了授权请求" ; return ; case ASAuthorizationErrorFailed: errorMsg = @"授权请求失败" ; break ; case ASAuthorizationErrorInvalidResponse: errorMsg = @"授权请求响应无效" ; break ; case ASAuthorizationErrorNotHandled: errorMsg = @"未能处理授权请求" ; break ; case ASAuthorizationErrorUnknown: errorMsg = @"授权请求失败未知原因" ; break ; } [self .errorSubject sendNext:LMError(errorMsg)]; }
其他可选项 苹果提供的登录按钮 1 ASAuthorizationAppleIDButton *button = [ASAuthorizationAppleIDButton buttonWithType:ASAuthorizationAppleIDButtonTypeSignIn style:ASAuthorizationAppleIDButtonStyleWhiteOutline];
其中
1 2 3 4 5 6 7 8 9 10 11 12 13 typedef NS_ENUM (NSInteger , ASAuthorizationAppleIDButtonType ) { ASAuthorizationAppleIDButtonTypeSignIn , // 按钮文字显示 :通过Apple 登录 ASAuthorizationAppleIDButtonTypeContinue , // 按钮文字显示 :通过Apple 继续 ASAuthorizationAppleIDButtonTypeDefault = // 默认第一个 ASAuthorizationAppleIDButtonTypeSignIn , } typedef NS_ENUM (NSInteger , ASAuthorizationAppleIDButtonStyle ) { ASAuthorizationAppleIDButtonStyleWhite , // 白底黑字 ASAuthorizationAppleIDButtonStyleWhiteOutline , // 黑字白框 ASAuthorizationAppleIDButtonStyleBlack , // 黑底白字 }
授权成功的回调可以来自于其他地方 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 - (void)authorizationController:(ASAuthorizationController * )controller didCompleteWithAuthorization:(ASAuthorization * )authorization API_AVAILABLE (ios(13.0 )){ NSLog (@"%s" , __FUNCTION__); NSLog (@"%@" , controller); NSLog (@"%@" , authorization); NSLog (@"authorization.credential:%@" , authorization.credential); NSMutableString * mStr = [NSMutableString string]; mStr = [_appleIDInfoTextView.text mutableCopy]; if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class ]]) { ASAuthorizationAppleIDCredential * appleIDCredential = authorization.credential; NSString * user = appleIDCredential.user; [[NSUserDefaults standardUserDefaults] setValue:user forKey:QiShareCurrentIdentifier ]; [mStr appendString:user? :@"" ]; NSString * familyName = appleIDCredential.fullName.familyName; [mStr appendString:familyName? :@"" ]; NSString * givenName = appleIDCredential.fullName.givenName; [mStr appendString:givenName? :@"" ]; NSString * email = appleIDCredential.email; [mStr appendString:email? :@"" ]; NSLog (@"mStr:%@" , mStr); [mStr appendString:@"\n " ]; _appleIDInfoTextView.text = mStr; } else if ([authorization.credential isKindOfClass:[ASPasswordCredential class ]]) { ASPasswordCredential * passwordCredential = authorization.credential; NSString * user = passwordCredential.user; NSString * password = passwordCredential.password; [mStr appendString:user? :@"" ]; [mStr appendString:password? :@"" ]; [mStr appendString:@"\n " ]; NSLog (@"mStr:%@" , mStr); _appleIDInfoTextView.text = mStr; } else { NSLog (@"授权信息均不符" ); mStr = [@"授权信息均不符" mutableCopy]; _appleIDInfoTextView.text = mStr; } }
已经使用Sign In With Apple登录过app的用户 执行已经登录过的场景。如果设备中存在iCloud Keychain 凭证或者AppleID 凭证提示用户直接使用TouchID或FaceID登录即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 - (void )perfomExistingAccountSetupFlows { if (@available(iOS 13.0 , *)) { ASAuthorizationAppleIDProvider *appleIDProvider = [ASAuthorizationAppleIDProvider new ]; ASAuthorizationAppleIDRequest *authAppleIDRequest = [appleIDProvider createRequest]; ASAuthorizationPasswordRequest *passwordRequest = [[ASAuthorizationPasswordProvider new ] createRequest]; NSMutableArray <ASAuthorizationRequest *>* mArr = [NSMutableArray arrayWithCapacity:2 ]; if (authAppleIDRequest) { [mArr addObject:authAppleIDRequest]; } if (passwordRequest) { [mArr addObject:passwordRequest]; } NSArray <ASAuthorizationRequest *>* requests = [mArr copy]; ASAuthorizationController *authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:requests]; authorizationController.delegate = self ; authorizationController.presentationContextProvider = self ; [authorizationController performRequests]; } }
监听授权状态变化 监听授权状态改变,并且做出相应处理。授权状态有:
1 2 3 ASAuthorizationAppleIDProviderCredentialRevoked:授权状态失效(用户停止使用AppID 登录App ) ASAuthorizationAppleIDProviderCredentialAuthorized:已授权(已使用AppleID 登录过App ) ASAuthorizationAppleIDProviderCredentialNotFound:授权凭证缺失(可能是使用AppleID 登录过App )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 - (void)observeAuthticationState { if (@available (iOS 13.0 , * )) { ASAuthorizationAppleIDProvider * appleIDProvider = [ASAuthorizationAppleIDProvider new]; NSString * userIdentifier = [[NSUserDefaults standardUserDefaults] valueForKey:QiShareCurrentIdentifier ]; if (userIdentifier) { NSString * __block errorMsg = nil ; [appleIDProvider getCredentialStateForUserID:userIdentifier completion:^ (ASAuthorizationAppleIDProviderCredentialState credentialState, NSError * _Nullable error) { switch (credentialState) { case ASAuthorizationAppleIDProviderCredentialRevoked : errorMsg = @"苹果授权凭证失效" ; break ; case ASAuthorizationAppleIDProviderCredentialAuthorized : errorMsg = @"苹果授权凭证状态良好" ; break ; case ASAuthorizationAppleIDProviderCredentialNotFound : errorMsg = @"未发现苹果授权凭证" ; break ; } dispatch_async(dispatch_get_main_queue(), ^ { NSLog (@"SignInWithApple授权状态变化情况" ); NSLog (@"%@" , errorMsg); }); }]; } } }
使用通知的方式检测是否授权应用支持Sign In With Apple变化情况。如下的代码可以根据自己的业务场景去考虑放置的位置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 - (void)observeAppleSignInState { if (@available (iOS 13.0 , * )) { NSNotificationCenter * center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector (handleSignInWithAppleStateChanged:) name:ASAuthorizationAppleIDProviderCredentialRevokedNotification object:nil ]; } } - (void)handleSignInWithAppleStateChanged:(id)noti { NSLog (@"%s" , __FUNCTION__); NSLog (@"%@" , noti); } - (void)dealloc { if (@available (iOS 13.0 , * )) { [[NSNotificationCenter defaultCenter] removeObserver:self name:ASAuthorizationAppleIDProviderCredentialRevokedNotification object:nil ]; } }
重要(Important!)
最好使用苹果提供的按钮 ASAuthorizationAppleIDButton
(只有黑白两种颜色)
不用他的按钮的话建议使用显眼的颜色
尽量放在显眼位置(第一位)
不能比其他任何登录按钮要小
保证登录页面一屏就能看到苹果登录按钮,不能滚动后才能看到
按钮的最小宽高有需求(看苹果人机交互指南相关文档 )
如果登录后要绑定手机的话,就在备注里面写好 依据来源 http://www.cac.gov.cn/2016-11/07/c_1119867116_2.htm 指明(截图)第二十四条(苹果一般不会打开网页,建议下载个pdf给他)
如果不好好跟苹果爸爸的规矩来,那么可能会吃到2.1和4.0 (不要问我为什么知道)
(更新至2019/11/01)
最小宽度
最小高度
最小间距
140pt (140px @1x, 280px @2x)
30pt (30px @1x, 60px @2x)
1/10 of the button’s height)
参考其他教程 掘金