關(guān)于蘋(píng)果登陸 Sign In With Apple的總結(jié)

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

如下圖

2宾尚、項(xiàng)目配置

3巩掺、集成代碼

主要步驟:

使用ASAuthorizationAppleIDButton創(chuàng)建button,布局蚤蔓,添加點(diǎn)擊事件搏讶;

實(shí)現(xiàn)點(diǎn)擊事件:授權(quán)請(qǐng)求

授權(quán)代理實(shí)現(xiàn)(授權(quán)成功,授權(quán)失敺园浮)ASAuthorizationControllerDelegate

驗(yàn)證

已經(jīng)Sign In with Apple登陸過(guò)app的用戶棚赔,處理

監(jiān)聽(tīng)授權(quán)狀態(tài)改變

4、實(shí)現(xiàn)

使用ASAuthorizationAppleIDButton創(chuàng)建button,布局徘郭,添加點(diǎn)擊事件靠益;

-(void)createView

{ ? ?

? ? ? if(@available(iOS13.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:selfaction:@selector(appleIDButtonClicked)forControlEvents:UIControlEventTouchUpInside];

? ? ? ? [self.view addSubview:appleIDButton];

? ? ? }

}

實(shí)現(xiàn)點(diǎn)擊事件:授權(quán)請(qǐng)求

-(void)appleIDButtonClickedAPI_AVAILABLE(ios(13.0)){

//基于用戶的Apple ID授權(quán)用戶,生成用戶授權(quán)請(qǐng)求的一種機(jī)制

ASAuthorizationAppleIDProvider*provide=[[ASAuthorizationAppleIDProvideralloc]init];

//創(chuàng)建新的AppleID 授權(quán)請(qǐng)求

ASAuthorizationAppleIDRequest*request=provide.createRequest;

//在用戶授權(quán)期間請(qǐng)求的聯(lián)系信息

request.requestedScopes=@[ASAuthorizationScopeFullName,ASAuthorizationScopeEmail];

//由ASAuthorizationAppleIDProvider創(chuàng)建的授權(quán)請(qǐng)求 管理授權(quán)請(qǐng)求的控制器

ASAuthorizationController*controller=[[ASAuthorizationControlleralloc]initWithAuthorizationRequests:@[request]];

//設(shè)置授權(quán)控制器通知授權(quán)請(qǐng)求的成功與失敗的代理

controller.delegate=self;

//設(shè)置提供 展示上下文的代理残揉,在這個(gè)上下文中 系統(tǒng)可以展示授權(quán)界面給用戶

controller.presentationContextProvider=self;

//在控制器初始化期間啟動(dòng)授權(quán)流

[controller performRequests];

}

授權(quán)代理實(shí)現(xiàn)(授權(quán)成功胧后,授權(quán)失敗)ASAuthorizationControllerDelegate驗(yàn)證

#pragmamark - ASAuthorizationControllerDelegate

//授權(quán)成功的回調(diào)

/**

當(dāng)授權(quán)成功后抱环,我們可以通過(guò)這個(gè)拿到用戶的 userID壳快、email、fullName镇草、authorizationCode眶痰、identityToken 以及 realUserStatus 等信息。

*/

-(void)authorizationController:(ASAuthorizationController*)controller didCompleteWithAuthorization:(ASAuthorization*)authorizationAPI_AVAILABLE(ios(13.0)){

? ? ? ? ?if([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]){

? ? ? ? ? ? ? ? // 用戶登錄使用ASAuthorizationAppleIDCredential

? ? ? ? ? ? ? ? ASAuthorizationAppleIDCredential*credential=authorization.credential;

? ? ? ? ? ? ? ? //蘋(píng)果用戶唯一標(biāo)識(shí)符梯啤,該值在同一個(gè)開(kāi)發(fā)者賬號(hào)下的所有 App 下是一樣的竖伯,開(kāi)發(fā)者可以用該唯一標(biāo)識(shí)符與自己后臺(tái)系統(tǒng)的賬號(hào)體系綁定起來(lái)。

? ? ? ? ? ? ? ? NSString*userId=credential.user;

? ? ? ? ? ? ? ? ?NSString*state=credential.state;

? ? ? ? ? ? ? ? ?NSPersonNameComponents*fullName=credential.fullName;

? ? ? ? ? ? ? ? ?//蘋(píng)果用戶信息条辟,郵箱

? ? ? ? ? ? ? ? ?NSString*email=credential.email;

? ? ? ? ? ? ? ? ?NSString*authorizationCode=[[NSString alloc]initWithData:credential.authorizationCode encoding:NSUTF8StringEncoding];// refresh token

? ? ? ? /**

? ? ? ? 驗(yàn)證數(shù)據(jù)黔夭,用于傳給開(kāi)發(fā)者后臺(tái)服務(wù)器宏胯,然后開(kāi)發(fā)者服務(wù)器再向蘋(píng)果的身份驗(yàn)證服務(wù)端驗(yàn)證本次授權(quán)登錄請(qǐng)求數(shù)據(jù)的有效性和真實(shí)性羽嫡,詳見(jiàn) Sign In with Apple REST API。如果驗(yàn)證成功肩袍,可以根據(jù) userIdentifier 判斷賬號(hào)是否已存在杭棵,若存在,則返回自己賬號(hào)系統(tǒng)的登錄態(tài),若不存在魂爪,則創(chuàng)建一個(gè)新的賬號(hào)先舷,并返回對(duì)應(yīng)的登錄態(tài)給 App。

? ? ? ? */

? ? ? ? ? ? ? ? ? ? ?NSString*identityToken=[[NSString alloc]initWithData:credential.identityToken encoding:NSUTF8StringEncoding];/**

? ? ? ? ? ? ? ? ? ? ? 用于判斷當(dāng)前登錄的蘋(píng)果賬號(hào)是否是一個(gè)真實(shí)用戶

? ? ? ? ? ? ? ? ? ? ? ?取值有:unsupported滓侍、unknown蒋川、likelyReal。

? ? ? ? */

ASUserDetectionStatus realUserStatus=credential.realUserStatus;

// 存儲(chǔ)userId到keychain中撩笆,代碼省略······

}elseif([authorization.credential isKindOfClass:[ASPasswordCredential class]]){

// 用戶登錄使用現(xiàn)有的密碼憑證

ASPasswordCredential*passwordCredential=authorization.credential;

// 密碼憑證對(duì)象的用戶標(biāo)識(shí) 用戶的唯一標(biāo)識(shí)

NSString*user=passwordCredential.user;

// 密碼憑證對(duì)象的密碼

NSString*password=passwordCredential.password;

_appleIDInfoTextView.text=[NSString stringWithFormat:@"%@",passwordCredential];

}else{

}

}


//失敗的回調(diào)

-(void)authorizationController:(ASAuthorizationController*)controller didCompleteWithError:(NSError*)errorAPI_AVAILABLE(ios(13.0)){

}


#pragmamark - ASAuthorizationControllerPresentationContextProviding

//告訴代理應(yīng)該在哪個(gè)window 展示授權(quán)界面給用戶

-(ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController*)controllerAPI_AVAILABLE(ios(13.0)){

return ? self.view.window;

}

已經(jīng)Sign In with Apple登陸過(guò)app的用戶

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

2氮兵、新增ASAuthorizationPasswordRequest,如果 KeyChain 里面有登錄信息的話歹鱼,可以直接使用里面保存的用戶名和密碼進(jìn)行登錄泣栈。

-(void)perfomExistingAccountSetupFlows{

if(@available(iOS13.0,*)){

// 授權(quán)請(qǐng)求依賴于用于的AppleID

ASAuthorizationAppleIDRequest*authAppleIDRequest=[[ASAuthorizationAppleIDProvidernew]createRequest];

// 為了執(zhí)行鑰匙串憑證分享生成請(qǐng)求的一種機(jī)制

ASAuthorizationPasswordRequest*passwordRequest=[[ASAuthorizationPasswordProvidernew]createRequest];

NSMutableArray<ASAuthorizationRequest*>*mArr=[NSMutableArrayarrayWithCapacity:2];

if(authAppleIDRequest){

[mArr addObject:authAppleIDRequest];

}

if(passwordRequest){

[mArr addObject:passwordRequest];

}

// ASAuthorizationRequest:對(duì)于不同種類授權(quán)請(qǐng)求的基類

NSArray<ASAuthorizationRequest*>*requests=[mArr copy];

// 由ASAuthorizationAppleIDProvider創(chuàng)建的授權(quán)請(qǐng)求 管理授權(quán)請(qǐng)求的控制器

ASAuthorizationController*authorizationController=[[ASAuthorizationControlleralloc]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];

? ? }

}

在 App 使用過(guò)程中弥姻,通過(guò)通知方法來(lái)監(jiān)聽(tīng) revoked 狀態(tài)

-(void)observeAppleSignInState{

if(@available(iOS13.0,*)){

NSNotificationCenter*center=[NSNotificationCenter defaultCenter];

[center addObserver:selfselector:@selector(handleSignInWithAppleStateChanged:)name:ASAuthorizationAppleIDProviderCredentialRevokedNotification object:nil];

}

}

// 觀察SignInWithApple狀態(tài)改變

-(void)handleSignInWithAppleStateChanged:(id)noti{

}

程序啟動(dòng)時(shí)南片,監(jiān)聽(tīng)授權(quán)狀態(tài)

用戶終止 App 中使用 Sign in with Apple 功能;

用戶在設(shè)置里注銷了 AppleId時(shí)

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

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

-(void)observeAuthticationState

{

// 基于用戶的Apple ID 生成授權(quán)用戶請(qǐng)求的機(jī)制

ASAuthorizationAppleIDProvider*appleIDProvider=[ASAuthorizationAppleIDProvider new];

// 注意 存儲(chǔ)用戶標(biāo)識(shí)信息需要使用鑰匙串來(lái)存儲(chǔ) 這里使用NSUserDefaults 做的簡(jiǎn)單示例

NSString*userIdentifier=[[NSUserDefaults standardUserDefaults]valueForKey:@"ShareCurrentIdentifier"];

if(userIdentifier){

// 在回調(diào)中返回用戶的授權(quán)狀態(tài)

[appleIDProvider getCredentialStateForUserID:userIdentifier completion:^(ASAuthorizationAppleIDProviderCredentialState credentialState,NSError*_Nullable error){

// 蘋(píng)果證書(shū)的授權(quán)狀態(tài)

switch(credentialState)

{

case ?ASAuthorizationAppleIDProviderCredentialRevoked:

// 蘋(píng)果授權(quán)憑證失效

dispatch_async(dispatch_get_main_queue(),^{

//做對(duì)應(yīng)處理

});

break;

case ? ? ASAuthorizationAppleIDProviderCredentialAuthorized:

// 蘋(píng)果授權(quán)憑證狀態(tài)良好

dispatch_async(dispatch_get_main_queue(),^{

//做對(duì)應(yīng)處理

});

break;

case ? ASAuthorizationAppleIDProviderCredentialNotFound:

// 未發(fā)現(xiàn)蘋(píng)果授權(quán)憑證

// 可以引導(dǎo)用戶重新登錄

dispatch_async(dispatch_get_main_queue(),^{

//做對(duì)應(yīng)處理

});

break;

default:

break;

}

}];

}

}

官網(wǎng)swift版demo和改編的OC版 ? ?https://github.com/wanggang1128/WGSignInWithApple

http://www.reibang.com/p/921ea520e8b3

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市定血,隨后出現(xiàn)的幾起案子赔癌,更是在濱河造成了極大的恐慌,老刑警劉巖澜沟,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灾票,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡茫虽,警方通過(guò)查閱死者的電腦和手機(jī)刊苍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)濒析,“玉大人正什,你說(shuō)我怎么就攤上這事『判樱” “怎么了婴氮?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我主经,道長(zhǎng)荣暮,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任罩驻,我火速辦了婚禮穗酥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘惠遏。我一直安慰自己迷扇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布爽哎。 她就那樣靜靜地躺著蜓席,像睡著了一般。 火紅的嫁衣襯著肌膚如雪课锌。 梳的紋絲不亂的頭發(fā)上厨内,一...
    開(kāi)封第一講書(shū)人閱讀 52,158評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音渺贤,去河邊找鬼雏胃。 笑死,一個(gè)胖子當(dāng)著我的面吹牛志鞍,可吹牛的內(nèi)容都是我干的瞭亮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼固棚,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼统翩!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起此洲,我...
    開(kāi)封第一講書(shū)人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤厂汗,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后呜师,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體娶桦,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年汁汗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了衷畦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡知牌,死狀恐怖祈争,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情送爸,我是刑警寧澤铛嘱,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站袭厂,受9級(jí)特大地震影響墨吓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜纹磺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一帖烘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧橄杨,春花似錦秘症、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至采转,卻和暖如春聪廉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背故慈。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工板熊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人察绷。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓干签,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親拆撼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子容劳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359