Sign In With Apple總結(jié)

1、配置app套餐的Identifiers支持Sign In With Apple

如下圖

2、項目配置

3、集成代碼

主要步驟:
  • 使用ASAuthorizationAppleIDButton創(chuàng)建button,布局,添加點擊事件;
  • 實現(xiàn)點擊事件:授權(quán)請求
  • 授權(quán)代理實現(xiàn)(授權(quán)成功,授權(quán)失敗)ASAuthorizationControllerDelegate
  • 驗證
  • 已經(jīng)Sign In with Apple登陸過app的用戶,處理
  • 監(jiān)聽授權(quán)狀態(tài)改變

4、實現(xiàn)

使用ASAuthorizationAppleIDButton創(chuàng)建button,布局,添加點擊事件;
- (void)createView {    
    if (@available(iOS 13.0, *)) {
        ASAuthorizationAppleIDButton *appleIDButton = [[ASAuthorizationAppleIDButton alloc] init];
        appleIDButton.frame = CGRectMake(50, 100+CGRectGetHeight(self.view.frame) * 0.4, CGRectGetWidth(self.view.frame)-100, 50);
        [appleIDButton addTarget:self action:@selector(appleIDButtonClicked) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:appleIDButton];
    }
}
實現(xiàn)點擊事件:授權(quán)請求
- (void)appleIDButtonClicked API_AVAILABLE(ios(13.0)) {
    //基于用戶的Apple ID授權(quán)用戶,生成用戶授權(quán)請求的一種機制
    ASAuthorizationAppleIDProvider *provide = [[ASAuthorizationAppleIDProvider alloc] init];
    //創(chuàng)建新的AppleID 授權(quán)請求
    ASAuthorizationAppleIDRequest *request = provide.createRequest;
    //在用戶授權(quán)期間請求的聯(lián)系信息
    request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
    //由ASAuthorizationAppleIDProvider創(chuàng)建的授權(quán)請求 管理授權(quán)請求的控制器
    ASAuthorizationController *controller = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
    //設(shè)置授權(quán)控制器通知授權(quán)請求的成功與失敗的代理
    controller.delegate = self;
    //設(shè)置提供 展示上下文的代理,在這個上下文中 系統(tǒng)可以展示授權(quán)界面給用戶
    controller.presentationContextProvider = self;
    //在控制器初始化期間啟動授權(quán)流
    [controller performRequests];
}
授權(quán)代理實現(xiàn)(授權(quán)成功,授權(quán)失?。〢SAuthorizationControllerDelegate
驗證
#pragma mark - ASAuthorizationControllerDelegate
//授權(quán)成功的回調(diào)
/**
 當(dāng)授權(quán)成功后,我們可以通過這個拿到用戶的 userID、email、fullName、authorizationCode、identityToken 以及 realUserStatus 等信息。
 */
-(void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)) {
    
    if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
        
        // 用戶登錄使用ASAuthorizationAppleIDCredential
        ASAuthorizationAppleIDCredential *credential = authorization.credential;
        
        //蘋果用戶唯一標(biāo)識符,該值在同一個開發(fā)者賬號下的所有 App 下是一樣的,開發(fā)者可以用該唯一標(biāo)識符與自己后臺系統(tǒng)的賬號體系綁定起來。
        NSString *userId = credential.user;
        NSString *state = credential.state;
        NSPersonNameComponents *fullName = credential.fullName;
        //蘋果用戶信息,郵箱
        NSString *email = credential.email;
        NSString *authorizationCode = [[NSString alloc] initWithData:credential.authorizationCode encoding:NSUTF8StringEncoding]; // refresh token
        /**
         驗證數(shù)據(jù),用于傳給開發(fā)者后臺服務(wù)器,然后開發(fā)者服務(wù)器再向蘋果的身份驗證服務(wù)端驗證本次授權(quán)登錄請求數(shù)據(jù)的有效性和真實性,詳見 Sign In with Apple REST API。如果驗證成功,可以根據(jù) userIdentifier 判斷賬號是否已存在,若存在,則返回自己賬號系統(tǒng)的登錄態(tài),若不存在,則創(chuàng)建一個新的賬號,并返回對應(yīng)的登錄態(tài)給 App。
         */
        NSString *identityToken = [[NSString alloc] initWithData:credential.identityToken encoding:NSUTF8StringEncoding];
        /**
         用于判斷當(dāng)前登錄的蘋果賬號是否是一個真實用戶
         取值有:unsupported、unknown、likelyReal。
         */
        ASUserDetectionStatus realUserStatus = credential.realUserStatus;
        // 存儲userId到keychain中,代碼省略
       ······
               
    } 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;
        
        _appleIDInfoTextView.text = [NSString stringWithFormat:@"%@",passwordCredential];
        
    } else {
        
    }
}

//失敗的回調(diào)
-(void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)) {
    
}

#pragma mark - ASAuthorizationControllerPresentationContextProviding
//告訴代理應(yīng)該在哪個window 展示授權(quán)界面給用戶
-(ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller API_AVAILABLE(ios(13.0)) {
    
    return self.view.window;
}
已經(jīng)Sign In with Apple登陸過app的用戶

1、如果設(shè)備中存在iCloud Keychain憑證或者AppleID憑證,提示用戶直接使用TouchID或FaceID登錄即可。

2、新增ASAuthorizationPasswordRequest,如果 KeyChain 里面有登錄信息的話,可以直接使用里面保存的用戶名和密碼進行登錄。

- (void)perfomExistingAccountSetupFlows {
    if (@available(iOS 13.0, *)) {
                
        // 授權(quán)請求依賴于用于的AppleID
        ASAuthorizationAppleIDRequest *authAppleIDRequest = [[ASAuthorizationAppleIDProvider new] createRequest]; 
        // 為了執(zhí)行鑰匙串憑證分享生成請求的一種機制
        ASAuthorizationPasswordRequest *passwordRequest = [[ASAuthorizationPasswordProvider new] createRequest];
        NSMutableArray <ASAuthorizationRequest *> *mArr = [NSMutableArray arrayWithCapacity:2];
        if (authAppleIDRequest) {
            [mArr addObject:authAppleIDRequest];
        }
        if (passwordRequest) {
            [mArr addObject:passwordRequest];
        } 
        // ASAuthorizationRequest:對于不同種類授權(quán)請求的基類
        NSArray <ASAuthorizationRequest *> *requests = [mArr copy];
        // 由ASAuthorizationAppleIDProvider創(chuàng)建的授權(quán)請求 管理授權(quán)請求的控制器
        ASAuthorizationController *authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:requests];
        // 設(shè)置授權(quán)控制器通知授權(quán)請求的成功與失敗的代理
        authorizationController.delegate = self;
        // 設(shè)置提供 展示上下文的代理,在這個上下文中 系統(tǒng)可以展示授權(quán)界面給用戶
        authorizationController.presentationContextProvider = self;
        // 在控制器初始化期間啟動授權(quán)流
        [authorizationController performRequests];
    }
}
在 App 使用過程中,通過通知方法來監(jiān)聽 revoked 狀態(tài)

- (void)observeAppleSignInState {
    if (@available(iOS 13.0, *)) {
        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
        [center addObserver:self selector:@selector(handleSignInWithAppleStateChanged:) name:ASAuthorizationAppleIDProviderCredentialRevokedNotification object:nil];
    }
}

// 觀察SignInWithApple狀態(tài)改變
- (void)handleSignInWithAppleStateChanged:(id)noti {
    
}
程序啟動時,監(jiān)聽授權(quán)狀態(tài)

用戶終止 App 中使用 Sign in with Apple 功能;
用戶在設(shè)置里注銷了 AppleId時

App 需要獲取到這些狀態(tài),然后做退出登錄操作,或者重新登錄。

我們需要在 App 啟動的時候,通過 getCredentialState:completion: 來獲取當(dāng)前用戶的授權(quán)狀態(tài)。

- (void)observeAuthticationState {
    
    // 基于用戶的Apple ID 生成授權(quán)用戶請求的機制
    ASAuthorizationAppleIDProvider *appleIDProvider = [ASAuthorizationAppleIDProvider new];
    // 注意 存儲用戶標(biāo)識信息需要使用鑰匙串來存儲 這里使用NSUserDefaults 做的簡單示例
    NSString *userIdentifier = [[NSUserDefaults standardUserDefaults] valueForKey:@"ShareCurrentIdentifier"];
    
    if (userIdentifier) {
        
        // 在回調(diào)中返回用戶的授權(quán)狀態(tài)
        [appleIDProvider getCredentialStateForUserID:userIdentifier completion:^(ASAuthorizationAppleIDProviderCredentialState credentialState, NSError * _Nullable error) {
            
            // 蘋果證書的授權(quán)狀態(tài)
            switch (credentialState) {
                case ASAuthorizationAppleIDProviderCredentialRevoked:
                    // 蘋果授權(quán)憑證失效
                    dispatch_async(dispatch_get_main_queue(), ^{
                        //做對應(yīng)處理
                    });
                    break;
                case ASAuthorizationAppleIDProviderCredentialAuthorized:
                    // 蘋果授權(quán)憑證狀態(tài)良好
                    dispatch_async(dispatch_get_main_queue(), ^{
                        //做對應(yīng)處理
                    });
                    break;
                case ASAuthorizationAppleIDProviderCredentialNotFound:
                    // 未發(fā)現(xiàn)蘋果授權(quán)憑證
                    // 可以引導(dǎo)用戶重新登錄
                    dispatch_async(dispatch_get_main_queue(), ^{
                        //做對應(yīng)處理
                    });
                    break;
                    
                default:
                    break;
            }
            
        }];
    }
}

官網(wǎng)swift版demo和改編的OC版

參考文章:

Sign In With Apple(一)
Sign In with Apple - 使用蘋果賬號登錄你的應(yīng)用
iOS 13 適配
Sign in with Apple
iOS 13-Sign In with Apple

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容