在 WWDC 2019 上拉背,蘋果推出了自家的 Sign in with Apple 功能员舵。iOS13之后工扎,App上如果有如”微信授權(quán)登錄”的第三方登錄泪酱,就必須提供“蘋果登錄”選項。(強制性的呦??) 蘋果官網(wǎng)有介紹 自行翻譯
一茴肥、初識SignInWithApple登錄授權(quán)原理
二坚踩、蘋果開發(fā)者后臺配置
1、配置Identifiers
2、配置項目
三础锐、編輯蘋果按鈕代碼
3.0嗓节、代碼引入 #import "AppDelegate.h"
#import "AppDelegate.h"
#pragma mark - 蘋果賬號登錄
#import <AuthenticationServices/AuthenticationServices.h>
@interface AppDelegate ()
@end
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
#pragma mark- 蘋果賬號登錄配置
[self observeAuthticationState];
return YES;
}
#pragma mark - Private functions 用戶注銷 AppleId 或 停止使用 Apple ID 的狀態(tài)處理
// 觀察授權(quán)狀態(tài)
- (void)observeAuthticationState {
if (@available(iOS 13.0, *)) {
// 注意 存儲用戶標(biāo)識信息需要使用鑰匙串來存儲 這里使用NSUserDefaults 做的簡單示例
NSString *userIdentifier = [[NSUserDefaults standardUserDefaults] valueForKey:@"appleID"];
if (userIdentifier) {
ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];
[appleIDProvider getCredentialStateForUserID:userIdentifier
completion:^(ASAuthorizationAppleIDProviderCredentialState credentialState, NSError * _Nullable error) {
switch (credentialState) {
case ASAuthorizationAppleIDProviderCredentialAuthorized:
// 授權(quán)狀態(tài)有效
break;
case ASAuthorizationAppleIDProviderCredentialRevoked:
// 蘋果賬號登錄的憑據(jù)已被移除,需解除綁定并重新引導(dǎo)用戶使用蘋果登錄
break;
case ASAuthorizationAppleIDProviderCredentialNotFound:
// 未登錄授權(quán)郁稍,直接彈出登錄頁面赦政,引導(dǎo)用戶登錄
break;
case ASAuthorizationAppleIDProviderCredentialTransferred:
// 授權(quán)AppleID提供者憑據(jù)轉(zhuǎn)移
break;
}
}];
}
}
}
3.1、創(chuàng)建登錄按鈕(可以自己自定義按鈕耀怜,也可以使用蘋果原生按鈕)
示例以蘋果官方按鈕演示(app登錄頁面創(chuàng)建)
//登錄也引入頭文件
#import <AuthenticationServices/AuthenticationServices.h>
//添加代理
@interface ViewController ()<ASAuthorizationControllerDelegate,ASAuthorizationControllerPresentationContextProviding>
@end
然后在viewDidLoad創(chuàng)建按鈕
#pragma mark - iOS13 才支持 系統(tǒng)提供的 登錄按鈕 要做下判斷
if (@available(iOS 13.0, *)){
// Sign In With Apple 按鈕
ASAuthorizationAppleIDButton *appleIDBtn3 = [ASAuthorizationAppleIDButton buttonWithType:ASAuthorizationAppleIDButtonTypeDefault style:ASAuthorizationAppleIDButtonStyleWhiteOutline];
appleIDBtn3.frame = CGRectMake(30, 560, self.view.bounds.size.width - 60, 40);
[appleIDBtn3 addTarget:self action:@selector(didAppleIDBtnClicked) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:appleIDBtn3];
}
運行結(jié)果顯示按鈕的顏色可以自行設(shè)置恢着,黑的白的都有
3.2、點擊事件觸發(fā)的代理
#pragma mark - 蘋果登錄 發(fā)起授權(quán)登錄請求 Begin ================== http://www.reibang.com/p/483b998f2370
-(void)didAppleIDBtnClicked{
if (@available(iOS 13.0, *)) {
// Authorization 發(fā)起授權(quán)登錄請求
/*
ASAuthorizationAppleIDProvider 這個類比較簡單财破,頭文件中可以看出掰派,主要用于創(chuàng)建一個 ASAuthorizationAppleIDRequest 以及獲取對應(yīng) userID 的用戶授權(quán)狀態(tài)。
*/
ASAuthorizationAppleIDProvider * appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];
ASAuthorizationAppleIDRequest * authAppleIDRequest = [appleIDProvider createRequest];
// ASAuthorizationPasswordRequest * passwordRequest = [[[ASAuthorizationPasswordProvider alloc] init] createRequest];
NSMutableArray <ASAuthorizationRequest *> * array = [NSMutableArray arrayWithCapacity:2];
if (authAppleIDRequest) {
[array addObject:authAppleIDRequest];
}
NSArray <ASAuthorizationRequest *> * requests = [array copy];
ASAuthorizationController * authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:requests];
authorizationController.delegate = self;
authorizationController.presentationContextProvider = self;
[authorizationController performRequests];
} else {
// 處理不支持系統(tǒng)版本
NSLog(@"系統(tǒng)不支持Apple登錄");
}
}
#pragma mark- ASAuthorizationControllerDelegate
// 授權(quán)成功
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)) {
if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
ASAuthorizationAppleIDCredential * credential = authorization.credential;
// 蘋果用戶唯一標(biāo)識符左痢,該值在同一個開發(fā)者賬號下的所有 App 下是一樣的靡羡,開發(fā)者可以用該唯一標(biāo)識符與自己后臺系統(tǒng)的賬號體系綁定起來系洛。
NSString * userID = credential.user;
// 蘋果用戶信息 如果授權(quán)過,可能無法再次獲取該信息
NSPersonNameComponents * fullName = credential.fullName;
NSString * email = credential.email;
// 服務(wù)器驗證需要使用的參數(shù)
NSString * authorizationCode = [[NSString alloc] initWithData:credential.authorizationCode encoding:NSUTF8StringEncoding];
NSString * identityToken = [[NSString alloc] initWithData:credential.identityToken encoding:NSUTF8StringEncoding];
// 用于判斷當(dāng)前登錄的蘋果賬號是否是一個真實用戶略步,取值有:unsupported描扯、unknown、likelyReal
ASUserDetectionStatus realUserStatus = credential.realUserStatus;
[[NSUserDefaults standardUserDefaults] setObject:userID forKey:@"appleID"];
NSLog(@"userID: %@", userID);
NSLog(@"fullName: %@", fullName);
NSLog(@"email: %@", email);
NSLog(@"authorizationCode: %@", authorizationCode);
NSLog(@"identityToken: %@", identityToken);
NSLog(@"realUserStatus: %@", @(realUserStatus));
NSString * loging = [NSString stringWithFormat:@"參數(shù)1:%@參數(shù)2:%@參數(shù)3:%@",userID,email,identityToken];
NSLog(@"Sign in with Apple++++++++++%@",loging);
}
else if ([authorization.credential isKindOfClass:[ASPasswordCredential class]]) {
// 用戶登錄使用現(xiàn)有的密碼憑證
ASPasswordCredential * passwordCredential = authorization.credential;
// 密碼憑證對象的用戶標(biāo)識 用戶的唯一標(biāo)識
NSString * user = passwordCredential.user;
// 密碼憑證對象的密碼
NSString * password = passwordCredential.password;
NSLog(@"userID: %@", user);
NSLog(@"password: %@", password);
} else {
}
}
// 授權(quán)失敗
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)) {
NSString *errorMsg = nil;
switch (error.code) {
case ASAuthorizationErrorCanceled:
errorMsg = @"用戶取消了授權(quán)請求";
break;
case ASAuthorizationErrorFailed:
errorMsg = @"授權(quán)請求失敗";
break;
case ASAuthorizationErrorInvalidResponse:
errorMsg = @"授權(quán)請求響應(yīng)無效";
break;
case ASAuthorizationErrorNotHandled:
errorMsg = @"未能處理授權(quán)請求";
break;
case ASAuthorizationErrorUnknown:
errorMsg = @"授權(quán)請求失敗未知原因";
break;
}
NSLog(@"%@", errorMsg);
}
#pragma mark- ASAuthorizationControllerPresentationContextProviding
- (ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller API_AVAILABLE(ios(13.0)){
return self.view.window;
}
#pragma mark- apple授權(quán)狀態(tài) 更改通知
- (void)handleSignInWithAppleStateChanged:(NSNotification *)notification
{
NSLog(@"%@", notification.userInfo);
}
#pragma mark - 蘋果授權(quán) End ========================
四趟薄、返回結(jié)果(上面已經(jīng)向Apple id發(fā)起了請求绽诚,該返回給我們參數(shù)了,對吧杭煎!哈哈??)
2021-07-10 11:46:57.941899+0800 SignInWithAppleZA[5704:1240072] Sign in with Apple++++++++++userID參數(shù)為:001921.36778e4680b8499bb1f87637ca300daa.0111email參數(shù)為:(null)identityToken參數(shù)為:eyJraWQiOiJZdXlYb1kiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiWm9uZ0FuZy5TaWduSW5XaXRoQXBwbGVaQSIsImV4cCI6MTYyNTk3NTIxNywiaWF0IjoxNjI1ODg4ODE3LCJzdWIiOiIwMDE5MjEuMzY3NzhlNDY4MGI4NDk5YmIxZjg3NjM3Y2EzMDBkYWEuMDExMSIsImNfaGFzaCI6IlByNllJbDRVbDd3OUJXVjdIVFlZV1EiLCJhdXRoX3RpbWUiOjE2MjU4ODg4MTcsIm5vbmNlX3N1cHBvcnRlZCI6dHJ1ZX0.eqjsrrybCHwxunceE7keAI0xju1Z0wxph3fJrBrPLNfxda1QR1jYTTto_0t4K2UZ1FzWVVhaHsP3z3hdUjZDugGxEfkyb1E2sZsqPYh2a7IfkBEq4hKhWDxqpQ_uPr133fBbuPnRbllRcUoE2I6p7n7HPu3u425RY97KIomyTI-94GzoQ04y6fx6cS9WEJQtjOnF2Y7tfMDiPIaXzrK5f5lcVAvhxEkwcCPoLM8qsne8zJENcM_a_2VcsyFG3262hz9uIFBupL_IYZcXjsfZXtlXYVCqH2NLVpN4JAzewmD5Pg9KRRAkFEjB_zWhvdymffe1Xpc8GCAN2Q8FpbambA
4.0恩够、控制臺打印結(jié)果