苹果授权登录开发指南—swift版

一、需求场景

越来越多的App为了方便用户的快捷登录,已经采用QQ微信支付宝微博等一些系列快捷登录的方式。但是在苹果最新政策当中,苹果表示:咋回事儿?瞧不起我么?!

SO,苹果要求使用了第三方登录的平台,必须要提供苹果登录通道,而且还必须在样式上不得被忽视。必须保证大小和样式不区别于其他第三方登录的方式。另外说一句,如果你不想做,想审核的时候藏起来?

那么可能会触发2.3.1审核条款,同时可能下次审核时间将会被延时审核,得不偿失

二、Xocde配置

1.添加 sign In With Apple

2.配置成功后Xcode会自动添加环境变量SignInWithApple如图:

3.其他

Xcode 请登录着开发者账号进行配置,本文是登录这开发者账号的。

三、客户端代码实现-Swift

1.使用苹果官方提供的样式,参考链接

官方按钮样式截图:

2.自定义登录按钮

swift 复制代码
import AuthenticationServices

class LoginView: {

    func createView() {
        if #available(iOS 13.0, *) {

            NotificationCenter.default.addObserver(self, selector: #selector(handleSignInWithAppleStateChanged(noti:)), name: ASAuthorizationAppleIDProvider.credentialRevokedNotification, object: nil)

            let btn_apple = UIButton(type: .custom)
            btn_apple.addTarget(self, action: #selector(appleLogininAction), for: .touchUpInside)
            btn_apple.setBackgroundImage(UIImage(named: "youImage"), for: .normal)
            self.addSubview(btn_apple)
            btn_apple.snp.makeConstraints {
                $0.width.equalTo(33)
            }
        }
    }

    @objc func appleLogininAction() {
        if #available(iOS 13.0, *) {
        
            //不要使用let requests = [ASAuthorizationAppleIDProvider().createRequest(), ASAuthorizationPasswordProvider().createRequest()]
//ASAuthorizationPasswordProvider().createRequest()在第一次用苹果登录授权的时候会报错ASAuthorizationErrorUnknown 1000
            let requests = [ASAuthorizationAppleIDProvider().createRequest()]
            
            let authorizationController = ASAuthorizationController(authorizationRequests: requests)

            authorizationController.delegate = self

            authorizationController.presentationContextProvider = self

            authorizationController.performRequests()

        } else {
            // 处理不支持系统版本
        }
    }

    deinit {
        if #available(iOS 13.0, *) {
            NotificationCenter.default.removeObserver(self, name: ASAuthorizationAppleIDProvider.credentialRevokedNotification, object: nil)
        }
    }
}

@available(iOS 13.0, *)
extension LoginView: ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
    

    func authorizationController(controller:ASAuthorizationController, didCompleteWithAuthorization authorization:ASAuthorization) {

        if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential{
            
            // 苹果用户唯一标识符,该值在同一个开发者账号下的所有 App 下是一样的,开发者可以用该唯一标识符与自己后台系统的账号体系绑定起来。
            let user = appleIDCredential.user

            // 苹果用户信息 如果授权过,可能无法再次获取该信息
            let fullName = appleIDCredential.fullName
            
            let email = appleIDCredential.email
            
            // 服务器验证需要使用的参数
            let authorizationCode = String(data: appleIDCredential.authorizationCode!, encoding: String.Encoding.utf8)!
            let identityToken = String(data: appleIDCredential.identityToken!, encoding: String.Encoding.utf8)!
            
            // 用于判断当前登录的苹果账号是否是一个真实用户,取值有:unsupported、unknown、likelyReal
            let realUserStatus = appleIDCredential.realUserStatus;
            
            //对接登录接口,处理用户登录操作

        }
    }
    
    func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
        
        if let e = error as? ASAuthorizationError {
            var errorMsg = ""
            switch e.code {
            case .unknown:
                errorMsg = "授权请求失败未知原因"
            case .canceled:
                errorMsg = "用户取消了授权请求"
            case .invalidResponse:
                errorMsg = "授权请求响应无效"
            case .notHandled:
                errorMsg = "未能处理授权请求"
            case .failed:
                errorMsg = "授权请求失败"
            @unknown default:
                errorMsg = "授权请求失败其他原因"
            }
        }

    }
    
    func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
        return UIApplication.shared.keyWindow!
    }
    
}

四、避坑指南

1.配置后一直报错ASAuthorizationError.unknown

swift 复制代码
//走失败函数
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
//code":1000,"domain":"com.apple.AuthenticationServices.AuthorizationError
}
  • 解决方案

不要使用ASAuthorizationPasswordProvider().createRequest()!!!! ASAuthorizationPasswordProvider().createRequest()在第一次用苹果登录授权的时候会报错ASAuthorizationErrorUnknown 1000。但是如果你已经授权成功登录app了,第二次登录app授权时使用ASAuthorizationPasswordProvider创建request则不会报错unknow

2.提审注意事项

1.不要使用手机绑定!不要使用手机绑定!不要使用手机绑定!

苹果认为他们官方的这种登录方式已经足够安全,不需要在认证用户手机号的方式进行绑定信息。这块业务逻辑开发者可以自行调整。

2.需要注销功能,不然会触发 5.1.1条款。

被拒原文:

vbnet 复制代码
Guideline 5.1.1(v) - Data Collection and Storage

We noticed that your app supports account creation but does not appear to include an option to initiate account deletion.

Apps that support account creation must also offer account deletion to give App Store users more control of the data they've shared while using your app.

Next Steps

If your app already supports account deletion, reply to this message and let us know how to locate this feature. If your app does not support account deletion, revise your app to include an option to initiate account deletion and delete all user data you are not legally required to retain.

If you are unable to offer account deletion or need to provide additional customer service flows to facilitate and confirm account deletion, either because your app operates in a highly-regulated industry or for some other reason, reply to this message in App Store Connect and provide additional information or documentation. If you have questions regarding your legal obligations, check with your legal counsel.

五、登录按钮素材

相关推荐
前端Hardy23 分钟前
别再忽略 Promise 拒绝了!你的 Node.js 服务正在“静默自杀”
前端·javascript·面试
前端Hardy25 分钟前
别再被setTimeout闭包坑了!90% 的人都写错过这个经典循环
前端·javascript·vue.js
小林coding31 分钟前
专为程序员打造的简历模版来啦!覆盖前端、后端、测开、大模型等专业简历
前端·后端
前端Hardy31 分钟前
你的 Vue 组件正在偷偷吃掉内存!5 个常见的内存泄漏陷阱与修复方案
前端·javascript·面试
RaidenLiu42 分钟前
Flutter Platform Channel 底层架构解析 —— 从 BinaryMessenger 到跨平台消息通信机制
前端·flutter·前端框架
bluceli44 分钟前
CSS容器查询:响应式设计的新范式
前端·css
Tapir1 小时前
被 Karpathy 下场推荐的 NanoClaw 是什么来头
前端·后端·github
前端人类学1 小时前
深入解析JavaScript中的null与undefined:区别、用法及判断技巧
前端·javascript
ssshooter2 小时前
Tauri 项目实践:客户端与 Web 端的授权登录实现方案
前端·后端·rust
兆子龙2 小时前
【React】19 深度解析:掌握新一代 React 特性
前端·架构