1.允许项目 appleID 登录

 

 

 

 

 

 

 

swift

import UIKit
import AuthenticationServices

/// AppleId 登录
class TGSAppleIdManager: NSObject{
    static let share = TGSAppleIdManager()
    
    /// 失败回调
    private var failureHandle:((_ errtip: String)->Void)?
    
    /// 成功回调
    private var sucessHandle:(( _ identityToken: Data,  _ authorizationCode: Data, _ user: String)->Void)?
}

extension TGSAppleIdManager{
    
    /// 登录苹果ID
    /// - Parameters:
    ///   - sucessHandle: 成功回调
    ///   - failureHandle: 失败回调
    func loginAppleId(sucessHandle:(( _ identityToken: Data,
                                      _ authorizationCode: Data,
                                      _ user: String)->Void)?,
                      failureHandle:(( _ errtip: String)->Void)?){
        if #available(iOS 13.0, *) {
            self.sucessHandle = sucessHandle
            self.failureHandle = failureHandle
            //基于用户的Apple ID 授权用户,生成用户授权请求的一种机制
            let appleIdProvider =  ASAuthorizationAppleIDProvider()
            //创建新的Apple ID授权请求
            let request = appleIdProvider.createRequest()
            //在用户授权期间请求的联系信息
            request.requestedScopes = [ASAuthorization.Scope.email, ASAuthorization.Scope.fullName]
            //由ASAuthorizationAppleIDProvider创建的授权请求,管理授权请求的控制器
            let controller = ASAuthorizationController.init(authorizationRequests: [request])
            //设置授权控制器通知授权请求的成功与失败的代理
            controller.delegate = self;
            //提供展示上下文的代理,在这个上下文中,系统可以展示授权界面给用户
            controller.presentationContextProvider = self;
            controller.performRequests()
        }
    }
    
    //MARK:暂未测试
//    // 如果存在iCloud Keychain 凭证或者AppleID 凭证提示用户
//    func perfomExistingAccountSetupFlows() {
//        // 基于用户的Apple ID授权用户,生成用户授权请求的一种机制
//        if #available(iOS 13.0, *) {
//            let appleIDProvide = ASAuthorizationAppleIDProvider()
//            // 授权请求AppleID
//            let request = appleIDProvide.createRequest()
//            // 为了执行钥匙串凭证分享生成请求的一种机制
//            let passwordProvider = ASAuthorizationPasswordProvider()
//            let passwordRequest = passwordProvider.createRequest()
//            // 由ASAuthorizationAppleIDProvider创建的授权请求 管理授权请求的控制器
//            let controller = ASAuthorizationController.init(authorizationRequests: [request,passwordRequest])
//            // 设置授权控制器通知授权请求的成功与失败的代理
//            controller.delegate = self
//            // 设置提供 展示上下文的代理,在这个上下文中 系统可以展示授权界面给用户
//            controller.presentationContextProvider = self
//            // 在控制器初始化期间启动授权流
//            controller.performRequests()
//        }
//    }
//
//    private func loginWithServer(user:String,token:String,code:String) {
//        //向你的服务器验证 ,验证通过即可登录
//    }
}
//MARK: - 代理 ASAuthorizationControllerDelegate 处理数据回调
extension TGSAppleIdManager:ASAuthorizationControllerDelegate{

    //授权成功地回调
    @available(iOS 13.0, *)
    func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        if  let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential{
            let identityToken = appleIDCredential.identityToken ?? Data()
            let authorizationCode = appleIDCredential.authorizationCode ?? Data()
            let user = appleIDCredential.user
            sucessHandle?(identityToken, authorizationCode, user)
//            // 使用过授权的,可能获取不到以下三个参数
//            let familyName = appleIDCredential.fullName?.familyName ?? ""
//            let givenName = appleIDCredential.fullName?.givenName ?? ""
//            let email = appleIDCredential.email ?? ""
            
//            // 用于判断当前登录的苹果账号是否是一个真实用户,取值有:unsupported、unknown、likelyReal
//            let realUserStatus = appleIDCredential.realUserStatus
            
        }
        //MARK:暂未测试
//        else if let passworCreddential = authorization.credential as? ASPasswordCredential{
//            // 这个获取的是iCloud记录的账号密码,需要输入框支持iOS 12 记录账号密码的新特性,如果不支持,可以忽略
//            // Sign in using an existing iCloud Keychain credential.
//            // 用户登录使用现有的密码凭证
//            // 密码凭证对象的用户标识 用户的唯一标识
//            let user = passworCreddential.user
//            // 密码凭证对象的密码
//            let password = passworCreddential.password
//        }else{
//            // "授权信息不符合"
//        }
    }
    
    @available(iOS 13.0, *)
    func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
        var errorStr : String?
          switch (error as NSError).code {
              case ASAuthorizationError.canceled.rawValue :
                  errorStr = "用户取消了授权请求"
              case ASAuthorizationError.failed.rawValue :
                  errorStr = "授权请求失败"
              case ASAuthorizationError.invalidResponse.rawValue :
                  errorStr = "授权请求无响应"
              case ASAuthorizationError.notHandled.rawValue :
                  errorStr = "未能处理授权请求"
              case ASAuthorizationError.unknown.rawValue :
                  errorStr = "授权请求失败原因未知"
          default:
              break
          }
          if let _errorStr = errorStr {
            failureHandle?(_errorStr)
          }
    }
}

//MARK: - 代理 ASAuthorizationControllerPresentationContextProviding 管理视图弹出在哪里
extension TGSAppleIdManager:ASAuthorizationControllerPresentationContextProviding{
    @available(iOS 13.0, *)
    func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
        return TGSWindow
    }
}

 

 

OC 

.h 文件

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface AppleIDLoginTool : NSObject

@property (strong, nonatomic) RACSubject *delegateSubject;

- (void)loginWithAppleId;



@end

NS_ASSUME_NONNULL_END

 

 

.m文件

#import "AppleIDLoginTool.h"
#import <AuthenticationServices/AuthenticationServices.h>

@interface AppleIDLoginTool()<ASAuthorizationControllerDelegate,ASAuthorizationControllerPresentationContextProviding>

@end

@implementation AppleIDLoginTool

- (void)loginWithAppleId
{
    if (@available(iOS 13.0, *)) {
        //基于用户的Apple ID 授权用户,生成用户授权请求的一种机制
        ASAuthorizationAppleIDProvider *appleIdProvider = [[ASAuthorizationAppleIDProvider alloc] init];
        //创建新的Apple ID授权请求
        ASAuthorizationAppleIDRequest *request = appleIdProvider.createRequest;
        //在用户授权期间请求的联系信息
        request.requestedScopes = @[ASAuthorizationScopeEmail,ASAuthorizationScopeFullName];
        //由ASAuthorizationAppleIDProvider创建的授权请求,管理授权请求的控制器
        ASAuthorizationController *controller = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
        //设置授权控制器通知授权请求的成功与失败的代理
        controller.delegate = self;
        //提供展示上下文的代理,在这个上下文中,系统可以展示授权界面给用户
        controller.presentationContextProvider = self;
        [controller performRequests];
    }else{
        NSLog(@"system is lower");
    }
}


#pragma mark - appleId登录代理方法
//授权成功的方法
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization  API_AVAILABLE(ios(13.0)){
    if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
        ASAuthorizationAppleIDCredential *credential = (ASAuthorizationAppleIDCredential *)authorization.credential;
        NSString *user = credential.user;
        NSData *identityToken = credential.identityToken;
        NSData *code = credential.authorizationCode;
        NSString *token = [[NSString alloc] initWithData:identityToken encoding:NSUTF8StringEncoding];
        NSString *codeStr = [[NSString alloc] initWithData:code encoding:NSUTF8StringEncoding];
        //授权成功后, 拿到返回的全部数据, 根据需要和后台交互
        NSLog(@"user - %@ %@",user,identityToken);
        //保存apple返回的唯一标识符
        [[NSUserDefaults standardUserDefaults] setObject:user forKey:@"userIdentifier"];
        [[NSUserDefaults standardUserDefaults] synchronize];
        
        if (self.delegateSubject) {
            [self.delegateSubject sendNext:@{@"appleId":user,@"identityToken":token,@"code":codeStr}];
        }
        
    }else if ([authorization.credential isKindOfClass:[ASPasswordCredential class]]) {
        ASPasswordCredential *pdCredential = (ASPasswordCredential *)authorization.credential;
        // 密码凭证对象的用户标识 用户的唯一标识
        NSString *user = pdCredential.user;
        NSString *psd = pdCredential.password;
        NSLog(@"pduser - %@ %@",user,psd);
    }else{
        NSLog(@"授权信息不符");
    }
}

//授权失败的方法
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error  API_AVAILABLE(ios(13.0)){
    NSLog(@"错误信息  %@",error);
    NSString *errorMsg;
    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;
    }
    [HUDManager showTextHud:errorMsg];
    NSLog(@"errorMsg - %@",errorMsg);
}

- (nonnull ASPresentationAnchor)presentationAnchorForAuthorizationController:(nonnull ASAuthorizationController *)controller  API_AVAILABLE(ios(13.0)){
    return [Adaptive_iOS_13_ToolUtil iOS13_keyWindow];
}

@end

 

posted on 2020-12-23 11:54  懂事长qingzZ  阅读(1683)  评论(0编辑  收藏  举报