Sign in with Apple

一、功能提出

2019年6月3日,apple提出开发者们可以集成sign in with apple功能,其为跨平台的,iOS、macOS、watchOS、tvOS、JS均可使用,以下主要针对iOS平台。2019年9月12日,apple更新App Store Review Guidelines,提出“Starting today, new apps submitted to the App Storemust follow these guidelines. Existing apps and app updates must follow them by April 2020.”。最新的要求如下:(https://developer.apple.com/app-store/review/guidelines/#third-party-software)

developer.png

依据上述描述,在4月底前上线的万视达版本必须适配sign in with apple

二、开发sign in with apple注意事项

需要在apple后台打开该选项,并且重新生成Profiles配置文件,并安装到xcode中。如图所示:

4061583911945_.pic.jpg

服务端验证需要的文件,一个是私钥文件,一个是config.json文件
创建用于客户端省份验证的私钥,如下图:

4071583912511_.pic.jpg

点击右侧configure,选择之前创建的Primary App ID,保存之后,Apple会生成一个新的私钥,只能下载一次,目前已创建,私钥已保存。下载文件格式为p8,已转为.txt格式,方便后续查看。
3435798-0021d4982eb4a665.jpg

config.json文件格式如下:(目前创建的私钥等文件均未被使用,因服务器选择校验的方式不同)
4091583912967_.pic.jpg

在xcode中的准备工作:
在Xcode11 Signing & Capabilities中添加Sign In With Apple
image.png

在项目中的Build Phases中添加AuthenticationServices.framework.


4111583913212_.pic.jpg
三、实现

目前项目中QQ、微信三方登录使用的是ShareSDK,其最新版本也提供了apple登录,所以客户端集成sign in with apple使用ShareSDK提供的接口。注意仅支持iOS13及以上。
接口:返回apple账号信息
[ShareSDK authorize:SSDKPlatformTypeAppleAccount settings:nil onStateChanged:^(SSDKResponseState state, SSDKUser *user, NSError *error) {
if (state == SSDKResponseStateSuccess)
{
NSLog(@"rawData---%@",user.rawData);
NSLog(@"credential--%@",[user.credential rawData]);
}
else
{
NSLog(@"%@",error.userInfo);
}
}];
此接口第一次登录返回内容示例:(注意:email可选是否匿名,名称可以编辑,也可以不填写)

4151583913581_.pic_hd.jpg
4121583913423_.pic.jpg
4141583913578_.pic_hd.jpg
4131583913430_.pic.jpg

退出登录:在"设置->账户->密码与安全性->使⽤您的apple ID 的 App"中停止使用apple id,下次登录则同上方第一次登录。

接口:登录状态监听

[AppleAccountConnector addObserve:nil isFirstAddCallBack:YES forAppleAccountLoginStateHandler:^(SSDKAppleAccountState state, SSDKUser * _Nonnull user, NSError * _Nonnull error) {

if (state != SSDKAppleAccountStateAuthorized) {

}else{

if (user) {

NSLog(@"------%@", user.rawData);

}

}

}];

四、Apple提供自带的API实现,仅支持iOS13及以上

可以使用ASAuthorizationAppleIDButton选取适用的控件

按钮授权实现:

// 处理授权

  • (void)handleAuthorizationAppleIDButtonPress{

NSLog(@"////////");

if (@available(iOS 13.0, *)) {

// 基于用户的Apple ID授权用户,生成用户授权请求的一种机制

ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];

// 创建新的AppleID 授权请求

ASAuthorizationAppleIDRequest *appleIDRequest = [appleIDProvider createRequest];

// 在用户授权期间请求的联系信息

appleIDRequest.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];

// 由ASAuthorizationAppleIDProvider创建的授权请求 管理授权请求的控制器

ASAuthorizationController *authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[appleIDRequest]];

// 设置授权控制器通知授权请求的成功与失败的代理

authorizationController.delegate = self;

// 设置提供 展示上下文的代理,在这个上下文中 系统可以展示授权界面给用户

authorizationController.presentationContextProvider = self;

// 在控制器初始化期间启动授权流

[authorizationController performRequests];

}else{

// 处理不支持系统版本

NSLog(@"该系统版本不可用Apple登录");

}

}

如果存在iCloud Keychain 凭证或者AppleID 凭证提示用(如爱奇艺登录)

  • (void)perfomExistingAccountSetupFlows{

NSLog(@"///已经认证过了/////");

if (@available(iOS 13.0, *)) {

// 基于用户的Apple ID授权用户,生成用户授权请求的一种机制

ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];

// 授权请求AppleID

ASAuthorizationAppleIDRequest *appleIDRequest = [appleIDProvider createRequest];

// 为了执行钥匙串凭证分享生成请求的一种机制

ASAuthorizationPasswordProvider *passwordProvider = [[ASAuthorizationPasswordProvider alloc] init];

ASAuthorizationPasswordRequest *passwordRequest = [passwordProvider createRequest];

// 由ASAuthorizationAppleIDProvider创建的授权请求 管理授权请求的控制器

ASAuthorizationController *authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[appleIDRequest, passwordRequest]];

// 设置授权控制器通知授权请求的成功与失败的代理

authorizationController.delegate = self;

// 设置提供 展示上下文的代理,在这个上下文中 系统可以展示授权界面给用户

authorizationController.presentationContextProvider = self;

// 在控制器初始化期间启动授权流

[authorizationController performRequests];

}else{

// 处理不支持系统版本

NSLog(@"该系统版本不可用Apple登录");

}

}

授权回调如下:

//@optional 授权成功地回调

  • (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)){

NSLog(@"授权完成:::%@", authorization.credential);

NSLog(@"%s", FUNCTION);

NSLog(@"%@", controller);

NSLog(@"%@", authorization);

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

// 用户登录使用ASAuthorizationAppleIDCredential

ASAuthorizationAppleIDCredential *appleIDCredential = authorization.credential;

NSString *user = appleIDCredential.user;

// 使用过授权的,可能获取不到以下三个参数

NSString *familyName = appleIDCredential.fullName.familyName;

NSString *givenName = appleIDCredential.fullName.givenName;

NSString *email = appleIDCredential.email;

NSData *identityToken = appleIDCredential.identityToken;

NSData *authorizationCode = appleIDCredential.authorizationCode;

// 服务器验证需要使用的参数

NSString *identityTokenStr = [[NSString alloc] initWithData:identityToken encoding:NSUTF8StringEncoding];

NSString *authorizationCodeStr = [[NSString alloc] initWithData:authorizationCode encoding:NSUTF8StringEncoding];

NSLog(@"%@\n\n%@", identityTokenStr, authorizationCodeStr);

// Create an account in your system.

// 需要使用钥匙串的方式保存用户的唯一信息

// [YostarKeychain save:KEYCHAIN_IDENTIFIER(@"userIdentifier") data:user];

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

// 这个获取的是iCloud记录的账号密码,需要输入框支持iOS 12 记录账号密码的新特性,如果不支持,可以忽略

// Sign in using an existing iCloud Keychain credential.

// 用户登录使用现有的密码凭证

ASPasswordCredential *passwordCredential = authorization.credential;

// 密码凭证对象的用户标识 用户的唯一标识

NSString *user = passwordCredential.user;

// 密码凭证对象的密码

NSString *password = passwordCredential.password;

}else{

NSLog(@"授权信息均不符");

}

}

// 授权失败的回调

  • (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)){

// Handle error.

NSLog(@"Handle error:%@", error);

NSString *errorMsg = nil;

switch (error.code) {

case ASAuthorizationErrorCanceled:

errorMsg = @"用户取消了授权请求";

break;

case ASAuthorizationErrorFailed:

errorMsg = @"授权请求失败";

break;

case ASAuthorizationErrorInvalidResponse:

errorMsg = @"授权请求响应无效";

break;

case ASAuthorizationErrorNotHandled:

errorMsg = @"未能处理授权请求";

break;

case ASAuthorizationErrorUnknown:

errorMsg = @"授权请求失败未知原因";

break;

default:

break;

}

NSLog(@"%@", errorMsg);

}

苹果提供了登录按钮ASAuthorizationAppleIDButton (继承自UIControl)。

这个按钮具有两种文案类型和三个样式,分别是:

a@available(iOS 13.0, *)public enum ButtonType : Int {
case signIn
case continue
public static var default: ASAuthorizationAppleIDButton.ButtonType { get }
}

@available(iOS 13.0, *)public enum Style : Int {
case white
case whiteOutline
case black
}

·Apple 提供的登录按钮有三种外观:白色,带有黑色轮廓线的白色和黑色。

·文案有两种:Sign In with Apple 和 Continue with Apple。(具体使用哪个文案,根据自身业务需求来定)

按钮宽高默认值为 {width:130, height:30}。

比如背景色不能更改,文案只有两种可选,并且值不能修改,可以调整的只有圆角cornerRadius和size 。

按钮显示的文字都是英文的,不可以直接修改,不过可以添加本地化即可。

PS:
服务端验证参考资料
https://blog.csdn.net/wpf199402076118/article/details/99677412
官方资料
https://developer.apple.com/documentation/signinwithapplerestapi
https://www.jianshu.com/p/26383db8bf10

你可能感兴趣的:(Sign in with Apple)