SignInApple.m 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. //
  2. // SignInApple.m
  3. // SignInAppleDemo
  4. //
  5. // Created by Yostar on 2019/11/25.
  6. // Copyright © 2019 Yostar. All rights reserved.
  7. //
  8. #import "SignInApple.h"
  9. #import <AuthenticationServices/AuthenticationServices.h>
  10. #import "YostarKeychain.h"
  11. #define KEYCHAIN_IDENTIFIER(a) ([NSString stringWithFormat:@"%@_%@",[[NSBundle mainBundle] bundleIdentifier],a])
  12. @interface SignInApple () <ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding>
  13. @end
  14. @implementation SignInApple
  15. // 处理授权
  16. - (void)handleAuthorizationAppleIDButtonPress{
  17. NSLog(@"////////");
  18. if (@available(iOS 13.0, *)) {
  19. // 基于用户的Apple ID授权用户,生成用户授权请求的一种机制
  20. ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];
  21. // 创建新的AppleID 授权请求
  22. ASAuthorizationAppleIDRequest *appleIDRequest = [appleIDProvider createRequest];
  23. // 在用户授权期间请求的联系信息
  24. appleIDRequest.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
  25. // 由ASAuthorizationAppleIDProvider创建的授权请求 管理授权请求的控制器
  26. ASAuthorizationController *authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[appleIDRequest]];
  27. // 设置授权控制器通知授权请求的成功与失败的代理
  28. authorizationController.delegate = self;
  29. // 设置提供 展示上下文的代理,在这个上下文中 系统可以展示授权界面给用户
  30. authorizationController.presentationContextProvider = self;
  31. // 在控制器初始化期间启动授权流
  32. [authorizationController performRequests];
  33. }else{
  34. // 处理不支持系统版本
  35. NSLog(@"该系统版本不可用Apple登录");
  36. }
  37. }
  38. // 如果存在iCloud Keychain 凭证或者AppleID 凭证提示用户
  39. - (void)perfomExistingAccountSetupFlows{
  40. NSLog(@"///已经认证过了/////");
  41. if (@available(iOS 13.0, *)) {
  42. // 基于用户的Apple ID授权用户,生成用户授权请求的一种机制
  43. ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];
  44. // 授权请求AppleID
  45. ASAuthorizationAppleIDRequest *appleIDRequest = [appleIDProvider createRequest];
  46. // 为了执行钥匙串凭证分享生成请求的一种机制
  47. ASAuthorizationPasswordProvider *passwordProvider = [[ASAuthorizationPasswordProvider alloc] init];
  48. ASAuthorizationPasswordRequest *passwordRequest = [passwordProvider createRequest];
  49. // 由ASAuthorizationAppleIDProvider创建的授权请求 管理授权请求的控制器
  50. ASAuthorizationController *authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[appleIDRequest, passwordRequest]];
  51. // 设置授权控制器通知授权请求的成功与失败的代理
  52. authorizationController.delegate = self;
  53. // 设置提供 展示上下文的代理,在这个上下文中 系统可以展示授权界面给用户
  54. authorizationController.presentationContextProvider = self;
  55. // 在控制器初始化期间启动授权流
  56. [authorizationController performRequests];
  57. }else{
  58. // 处理不支持系统版本
  59. NSLog(@"该系统版本不可用Apple登录");
  60. }
  61. }
  62. #pragma mark - delegate
  63. //@optional 授权成功地回调
  64. - (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)){
  65. NSLog(@"授权完成:::%@", authorization.credential);
  66. NSLog(@"%s", __FUNCTION__);
  67. NSLog(@"%@", controller);
  68. NSLog(@"%@", authorization);
  69. if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
  70. // 用户登录使用ASAuthorizationAppleIDCredential
  71. ASAuthorizationAppleIDCredential *appleIDCredential = (ASAuthorizationAppleIDCredential *)authorization.credential;
  72. NSString *user = appleIDCredential.user;
  73. // 使用过授权的,可能获取不到以下三个参数
  74. // NSString *familyName = appleIDCredential.fullName.familyName;
  75. // NSString *givenName = appleIDCredential.fullName.givenName;
  76. // NSString *email = appleIDCredential.email;
  77. // NSLog(@"%@-%@-%@",familyName,givenName,email);
  78. // NSData *identityToken = appleIDCredential.identityToken;
  79. // NSData *authorizationCode = appleIDCredential.authorizationCode;
  80. // 服务器验证需要使用的参数
  81. // NSString *identityTokenStr = [[NSString alloc] initWithData:identityToken encoding:NSUTF8StringEncoding];
  82. // NSString *authorizationCodeStr = [[NSString alloc] initWithData:authorizationCode encoding:NSUTF8StringEncoding];
  83. // NSLog(@"%@\n\n%@", identityTokenStr, authorizationCodeStr);
  84. // Create an account in your system.
  85. // For the purpose of this demo app, store the userIdentifier in the keychain.
  86. // 需要使用钥匙串的方式保存用户的唯一信息
  87. [YostarKeychain save:KEYCHAIN_IDENTIFIER(@"userIdentifier") data:user];
  88. }else if ([authorization.credential isKindOfClass:[ASPasswordCredential class]]){
  89. // 这个获取的是iCloud记录的账号密码,需要输入框支持iOS 12 记录账号密码的新特性,如果不支持,可以忽略
  90. // Sign in using an existing iCloud Keychain credential.
  91. // 用户登录使用现有的密码凭证
  92. // ASPasswordCredential *passwordCredential = (ASPasswordCredential *)authorization.credential;
  93. // 密码凭证对象的用户标识 用户的唯一标识
  94. // NSString *user = passwordCredential.user;
  95. // // 密码凭证对象的密码
  96. // NSString *password = passwordCredential.password;
  97. // NSLog(@"%@-%@",user,password);
  98. }else{
  99. NSLog(@"授权信息均不符");
  100. }
  101. }
  102. // 授权失败的回调
  103. - (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)){
  104. // Handle error.
  105. NSLog(@"Handle error:%@", error);
  106. NSString *errorMsg = nil;
  107. switch (error.code) {
  108. case ASAuthorizationErrorCanceled:
  109. errorMsg = @"用户取消了授权请求";
  110. break;
  111. case ASAuthorizationErrorFailed:
  112. errorMsg = @"授权请求失败";
  113. break;
  114. case ASAuthorizationErrorInvalidResponse:
  115. errorMsg = @"授权请求响应无效";
  116. break;
  117. case ASAuthorizationErrorNotHandled:
  118. errorMsg = @"未能处理授权请求";
  119. break;
  120. case ASAuthorizationErrorUnknown:
  121. errorMsg = @"授权请求失败未知原因";
  122. break;
  123. default:
  124. break;
  125. }
  126. NSLog(@"%@", errorMsg);
  127. }
  128. // 告诉代理应该在哪个window 展示内容给用户
  129. - (ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller API_AVAILABLE(ios(13.0)){
  130. NSLog(@"88888888888");
  131. // 返回window
  132. return [UIApplication sharedApplication].windows.lastObject;
  133. }
  134. @end