苹果登录 Sign in with Apple

第三方登录现在已经成为了主流的登录方式,为了给自家用户带来更好的跨平台与跨设备体验,
苹果在今年的 WWDC2019 推出了属于自己的第三方登录服务 —— Sign in with Apple( iOS 13 及以上可用 )

官方介绍:
https://developer.apple.com/cn/news/?id=09122019b
https://developer.apple.com/cn/sign-in-with-apple/get-started/

接入参考(客户端):
https://mp.weixin.qq.com/s/FYLmFnuaq4DIEyvhgsE_zA
https://blog.csdn.net/n603482184/article/details/101444924

接入参考(服务端):
https://blog.csdn.net/wpf199402076118/article/details/99677412
https://mp.weixin.qq.com/s/xkxCnKqA0u-guEYcYCkcOg



难度指数:★☆☆☆☆
开发及运行环境: macOS 10.14.4 / Xcode 11 / iOS 13



开启苹果登录

  1. 在苹果开发者后台为应用开启苹果登录功能,具体参考上面的“接入参考(服务端)”

image.png

  1. 在项目工程中添加该功能

image.png

代码接入测试

GFAppleLoginManager.h

#import <Foundation/Foundation.h>
 
typedef void (^GFAppleLoginSuccessBlock)(NSString * userId, NSString * authCode, NSString * identityToken);
typedef void (^GFAppleLoginFailureBlock)(NSError * error);
 
@interface GFAppleLoginManager : NSObject
 
@property (nonatomic, assign, readonly) BOOL enable;
 
+ (instancetype)sharedManager;
- (void)login:(GFAppleLoginSuccessBlock)successBlock error:(GFAppleLoginFailureBlock)failureBlock;
 
@end

GFAppleLoginManager.m

#import "GFAppleLoginManager.h"
#import <AuthenticationServices/AuthenticationServices.h>
 
API_AVAILABLE(ios(13.0))
@interface GFAppleLoginManager() <ASAuthorizationControllerDelegate>
 
@property (nonatomic, retain) ASAuthorizationController * authorizationController;
@property (nonatomic, copy) GFAppleLoginSuccessBlock successBlock;
@property (nonatomic, copy) GFAppleLoginFailureBlock failureBlock;
 
@end
 
@implementation GFAppleLoginManager
 
- (BOOL)enable {
    return !!NSClassFromString(@"ASAuthorizationController");
}
 
+ (instancetype)sharedManager {
    static id instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}
 
- (void)login:(GFAppleLoginSuccessBlock)successBlock error:(GFAppleLoginFailureBlock)failureBlock {
    if (self.enable) {
        self.successBlock = successBlock;
        self.failureBlock = failureBlock;
        [self.authorizationController performRequests];
    }
}
 
#pragma mark - ASAuthorizationControllerDelegate
 
- (void)authorizationController:(ASAuthorizationController *)controller
   didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)) {
    if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]])       {
        ASAuthorizationAppleIDCredential * credential = authorization.credential;
        NSString * user = credential.user;
        NSString * authorizationCode = [[NSString alloc] initWithData:credential.authorizationCode encoding:NSUTF8StringEncoding];
        NSString * identityToken = [[NSString alloc] initWithData:credential.identityToken encoding:NSUTF8StringEncoding];
         
        if (self.successBlock) {
            self.successBlock(user, authorizationCode, identityToken);
        }
    }
}
 
- (void)authorizationController:(ASAuthorizationController *)controller
           didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)) {
    if (self.failureBlock) {
        self.failureBlock(error); // error.code => ASAuthorizationError
    }
}
 
- (ASAuthorizationController *)authorizationController API_AVAILABLE(ios(13.0)) {
    if (_authorizationController == nil) {
        ASAuthorizationAppleIDProvider * provider = [[ASAuthorizationAppleIDProvider alloc] init];
        ASAuthorizationAppleIDRequest * request = [provider createRequest];
        request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
         
        _authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
        _authorizationController.delegate = self;
    }
    return _authorizationController;
}
 
@end

测试代码

#import "GFAppleLoginManager.h"
#import <AuthenticationServices/AuthenticationServices.h>
 
if (@available(iOS 13.0, *)) {
    ASAuthorizationAppleIDButton *button = [ASAuthorizationAppleIDButton buttonWithType:ASAuthorizationAppleIDButtonTypeSignIn style:ASAuthorizationAppleIDButtonStyleWhite];
    button.bounds = CGRectMake(0, 0, 60, 60);
    button.cornerRadius = 30.0f;
    [button addTarget:self action:@selector(signInWithApple) forControlEvents:UIControlEventTouchUpInside];
    button.center = self.view.center;
    [self.view addSubview:button];
}
 
- (void)signInWithApple {
    if ([GFAppleLoginManager sharedManager].enable) {
        [[GFAppleLoginManager sharedManager] login:^(NSString *userId, NSString *authCode, NSString *identityToken) {
            NSLog(@"userId: %@", userId);
            NSLog(@"authCode: %@", authCode);
            NSLog(@"identityToken: %@", identityToken);
        } error:^(NSError *error) {
            NSLog(@"error: %@", error);
        }];
    }
}


苹果登录按钮设计

可以使用苹果提供的自带按钮,也可以自定义:
https://developer.apple.com/design/human-interface-guidelines/sign-in-with-apple/overview/
http://www.sohu.com/a/343050110_115785



用户需要做什么

用户在通过 Apple 登录时,需要先在“设置”中开启双重认证,否则会登录失败

image.png


当前文章所在位置:https://blog.csdn.net/MerryGOOT 《iOS 开发》文章目录



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章