iOS ~ Apple ID 登錄APP

【官網(wǎng):通過(guò) Apple 登錄,讓登錄變得輕松簡(jiǎn)單可婶∩盅郑】
【iOS 蘋果授權(quán)登錄(Sign in with Apple)系列之原生篇】

前言

2019年蘋果推出 蘋果登錄(Sign in with Apple)方式燎斩,要求2020年4月之后APP如果使用第三方或社交登錄服務(wù)(如 Facebook杯活、谷歌匆帚、 Twitter、Linkedln或亞馬遜等)轩猩,必須向用戶提供“以蘋果賬號(hào)登錄”服務(wù)的選項(xiàng)卷扮。

如果滿足以下條件,則可以不用蘋果登錄方式:

  1. 應(yīng)用專門使用公司自己的帳戶設(shè)置和登錄系統(tǒng)均践。
  2. 應(yīng)用是教育,企業(yè)或商業(yè)應(yīng)用摩幔,要求用戶使用現(xiàn)有的教育或企業(yè)帳戶登錄彤委。
  3. 應(yīng)用程序使用政府或行業(yè)支持的公民身份識(shí)別系統(tǒng)或電子ID來(lái)對(duì)用戶進(jìn)行身份驗(yàn)證。
  4. 應(yīng)用是特定第三方服務(wù)的客戶端或衡,要求用戶直接登錄其郵件焦影,社交媒體或其他第三方帳戶才能訪問(wèn)其內(nèi)容。
    官網(wǎng)詳細(xì)規(guī)則

集成流程

一封断、準(zhǔn)備工作

1.最低要求手機(jī)iOS系統(tǒng)ios13.0斯辰,蘋果電腦系統(tǒng)macos(10.15),開發(fā)工具Xcode11

  1. 登錄蘋果開發(fā)者賬號(hào)后臺(tái)坡疼,找到應(yīng)用的BundleId, 點(diǎn)擊進(jìn)去查看詳情信息, 開啟 Sign in with Apple 功能彬呻。
蘋果賬號(hào)后臺(tái)勾選Sign in with Apple 功能.png
  1. Xcode 里面 Signing & Capabilities 添加 Sign in with Apple 功能。

    Xcode添加 Sign in with Apple.png

二柄瑰、代碼集成(本流程比較簡(jiǎn)單,自定義的按鈕,沒(méi)有服務(wù)器驗(yàn)證流程)

因?yàn)槭亲远x的按鈕 沒(méi)有用蘋果系統(tǒng)自己的按鈕 ASAuthorizationAppleIDButton 闸氮,ASAuthorizationAppleIDButton尺寸會(huì)有一些限制,還得處理本地化語(yǔ)言。

image

1.導(dǎo)入頭文件教沾,添加代理

#import <AuthenticationServices/AuthenticationServices.h>
<ASAuthorizationControllerDelegate,ASAuthorizationControllerPresentationContextProviding>

2.viewDidLoad 方法中 判斷手機(jī)系統(tǒng)版本 注冊(cè)通知

    // 手機(jī)系統(tǒng)版本 不支持 時(shí) 隱藏蘋果登錄按鈕
    if (@available(iOS 13.0, *)) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleSignInWithAppleStateChanged:) name:ASAuthorizationAppleIDProviderCredentialRevokedNotification object:nil];
    } else {
        self.appleLoginBtn.hidden = YES;
    }

  1. 自定義的 蘋果登錄按鈕 的點(diǎn)擊事件中 處理
[self authorizationAppleID];

  1. 蘋果授權(quán)方法
#pragma mark- 授權(quán)蘋果ID
- (void)authorizationAppleID{
    if (@available(iOS 13.0, *)) {
        // 基于用戶的Apple ID授權(quán)用戶蒲跨,生成用戶授權(quán)請(qǐng)求的一種機(jī)制
        ASAuthorizationAppleIDProvider * appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];
        // 創(chuàng)建新的AppleID 授權(quán)請(qǐng)求
        ASAuthorizationAppleIDRequest * authAppleIDRequest = [appleIDProvider createRequest];
        // 在用戶授權(quán)期間請(qǐng)求的聯(lián)系信息
//        authAppleIDRequest.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
        //如果 KeyChain 里面也有登錄信息的話,可以直接使用里面保存的用戶名和密碼進(jìn)行登錄授翻。
//        ASAuthorizationPasswordRequest * passwordRequest = [[[ASAuthorizationPasswordProvider alloc] init] createRequest];

        NSMutableArray <ASAuthorizationRequest *> * array = [NSMutableArray arrayWithCapacity:2];
        if (authAppleIDRequest) {
            [array addObject:authAppleIDRequest];
        }
//        if (passwordRequest) {
//            [array addObject:passwordRequest];
//        }
        NSArray <ASAuthorizationRequest *> * requests = [array copy];
        // 由ASAuthorizationAppleIDProvider創(chuàng)建的授權(quán)請(qǐng)求 管理授權(quán)請(qǐng)求的控制器
        ASAuthorizationController * authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:requests];
         // 設(shè)置授權(quán)控制器通知授權(quán)請(qǐng)求的成功與失敗的代理
        authorizationController.delegate = self;
        // 設(shè)置提供 展示上下文的代理或悲,在這個(gè)上下文中 系統(tǒng)可以展示授權(quán)界面給用戶
        authorizationController.presentationContextProvider = self;
        // 在控制器初始化期間啟動(dòng)授權(quán)流
        [authorizationController performRequests];
    }
}

  1. 實(shí)現(xiàn)代理方法 授權(quán)成功 獲取 用戶的唯一標(biāo)識(shí) 傳給后臺(tái) 判斷該用戶是否綁定手機(jī)號(hào),如果綁定了直接登錄堪唐,如果沒(méi)綁定跳綁定手機(jī)號(hào)頁(yè)面
#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 = (ASAuthorizationAppleIDCredential *)authorization.credential;

        // 蘋果用戶唯一標(biāo)識(shí)符巡语,該值在同一個(gè)開發(fā)者賬號(hào)下的所有 App 下是一樣的,開發(fā)者可以用該唯一標(biāo)識(shí)符與自己后臺(tái)系統(tǒng)的賬號(hào)體系綁定起來(lái)羔杨。
        NSString * userID = credential.user;
        //把用戶的唯一標(biāo)識(shí) 傳給后臺(tái) 判斷該用戶是否綁定手機(jī)號(hào)捌臊,如果綁定了直接登錄,如果沒(méi)綁定跳綁定手機(jī)號(hào)頁(yè)面
//        // 蘋果用戶信息 如果授權(quán)過(guò)兜材,可能無(wú)法再次獲取該信息
//        NSPersonNameComponents * fullName = credential.fullName;
//        NSString * email = credential.email;
//
//        // 服務(wù)器驗(yàn)證需要使用的參數(shù)
//        NSString * authorizationCode = [[NSString alloc] initWithData:credential.authorizationCode encoding:NSUTF8StringEncoding];
//        NSString * identityToken = [[NSString alloc] initWithData:credential.identityToken encoding:NSUTF8StringEncoding];
//
//        // 用于判斷當(dāng)前登錄的蘋果賬號(hào)是否是一個(gè)真實(shí)用戶理澎,取值有:unsupported逞力、unknown、likelyReal
//        ASUserDetectionStatus realUserStatus = credential.realUserStatus;

//        NSLog(@"userID: %@", userID);
//        NSLog(@"fullName: %@", fullName);
//        NSLog(@"email: %@", email);
//        NSLog(@"authorizationCode: %@", authorizationCode);
//        NSLog(@"identityToken: %@", identityToken);
//        NSLog(@"realUserStatus: %@", @(realUserStatus));
    }else if ([authorization.credential isKindOfClass:[ASPasswordCredential class]]) {
        // 這個(gè)獲取的是iCloud記錄的賬號(hào)密碼糠爬,需要輸入框支持iOS 12 記錄賬號(hào)密碼的新特性寇荧,如果不支持,可以忽略
        // 用戶登錄使用現(xiàn)有的密碼憑證
        ASPasswordCredential * passwordCredential = (ASPasswordCredential *)authorization.credential;
        // 密碼憑證對(duì)象的用戶標(biāo)識(shí) 用戶的唯一標(biāo)識(shí)
        NSString * user = passwordCredential.user;

        //把用戶的唯一標(biāo)識(shí) 傳給后臺(tái) 判斷該用戶是否綁定手機(jī)號(hào)执隧,如果綁定了直接登錄揩抡,如果沒(méi)綁定跳綁定手機(jī)號(hào)頁(yè)面

//        // 密碼憑證對(duì)象的密碼
//        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)請(qǐng)求";
            break;
        case ASAuthorizationErrorFailed:
            errorMsg = @"授權(quán)請(qǐng)求失敗";
            break;
        case ASAuthorizationErrorInvalidResponse:
            errorMsg = @"授權(quán)請(qǐng)求響應(yīng)無(wú)效";
            break;
        case ASAuthorizationErrorNotHandled:
            errorMsg = @"未能處理授權(quán)請(qǐng)求";
            break;
        case ASAuthorizationErrorUnknown:
            errorMsg = @"授權(quán)請(qǐng)求失敗未知原因";
            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);
}
- (void)dealloc {
    if (@available(iOS 13.0, *)) {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:ASAuthorizationAppleIDProviderCredentialRevokedNotification object:nil];
    }
}

注意事項(xiàng)

1、首次登錄會(huì)返回所有參數(shù)镀琉,包括全名峦嗤、郵箱等(如果玩家登錄時(shí)拒絕提供真實(shí)的郵箱賬號(hào),蘋果會(huì)生成虛擬的郵箱賬號(hào))屋摔,二次登錄只會(huì)返回 UserID 和 授權(quán)碼烁设,其它信息不再返回!
2钓试、同一個(gè)開發(fā)者賬號(hào)下所有APP装黑,同一個(gè)apple id登陸時(shí),獲取的UserID 是一樣的弓熏。
3恋谭、兩個(gè)開發(fā)者賬號(hào)下的應(yīng)用,同一個(gè)apple id登陸時(shí)挽鞠,獲取的 UserID 不一樣
4疚颊、NSNotification.Name.ASAuthorizationAppleIDProviderCredentialRevoked, 系統(tǒng)在蘋果賬號(hào)登出時(shí)通知滞谢,此時(shí)應(yīng)用如果是蘋果登陸的用戶串稀,有沒(méi)有必要也登出賬號(hào)?
5狮杨、如果打開登錄界面時(shí)母截,設(shè)備的 iCloud Keychain 有 apple id 賬號(hào)可用時(shí),可以彈窗讓用戶選擇 iCloud Keychain 里的賬號(hào)來(lái)進(jìn)行登陸橄教。

image
image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末清寇,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子护蝶,更是在濱河造成了極大的恐慌华烟,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件持灰,死亡現(xiàn)場(chǎng)離奇詭異盔夜,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門喂链,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)返十,“玉大人,你說(shuō)我怎么就攤上這事椭微《纯樱” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵蝇率,是天一觀的道長(zhǎng)迟杂。 經(jīng)常有香客問(wèn)我,道長(zhǎng)本慕,這世上最難降的妖魔是什么排拷? 我笑而不...
    開封第一講書人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮间狂,結(jié)果婚禮上攻泼,老公的妹妹穿的比我還像新娘。我一直安慰自己鉴象,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開白布何鸡。 她就那樣靜靜地躺著纺弊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪骡男。 梳的紋絲不亂的頭發(fā)上淆游,一...
    開封第一講書人閱讀 52,268評(píng)論 1 309
  • 那天,我揣著相機(jī)與錄音隔盛,去河邊找鬼犹菱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛吮炕,可吹牛的內(nèi)容都是我干的腊脱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼龙亲,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼陕凹!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起鳄炉,我...
    開封第一講書人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤杜耙,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后拂盯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體佑女,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了团驱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摸吠。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖店茶,靈堂內(nèi)的尸體忽然破棺而出蜕便,到底是詐尸還是另有隱情,我是刑警寧澤贩幻,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布轿腺,位于F島的核電站,受9級(jí)特大地震影響丛楚,放射性物質(zhì)發(fā)生泄漏族壳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一趣些、第九天 我趴在偏房一處隱蔽的房頂上張望仿荆。 院中可真熱鬧,春花似錦坏平、人聲如沸拢操。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)令境。三九已至,卻和暖如春顾瞪,著一層夾襖步出監(jiān)牢的瞬間舔庶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工陈醒, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惕橙,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓钉跷,卻偏偏與公主長(zhǎng)得像弥鹦,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子尘应,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容