苹果登录signInWithApple踩坑—swift版(附oc参考)

一、先说踩坑问题

I.测试阶段的问题
  • 配置后一直报错ASAuthorizationError.unknown
//失败调代理方法
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
II.提交Appstore的注意点
  • 使用苹果授权登录后,不能强制要求用户再使用手机号注册,否则会被拒。

二、Xcode配置

1.添加sign In With Apple

苹果登录signInWithApple踩坑—swift版(附oc参考)

苹果登录signInWithApple踩坑—swift版(附oc参考)

2.配置成功后Xcode会自动添加环境变量SignInWithApple如图:
  • 添加成功后release和debug模式都支持SignInWithApple
    苹果登录signInWithApple踩坑—swift版(附oc参考)
3.登录开发者账户检查是否配置成功
  • 如果已经在Xcode中设置好了Team和Bundle Identifier那么配置完2.中步骤,这块会自动配置好。
    苹果登录signInWithApple踩坑—swift版(附oc参考)
    苹果登录signInWithApple踩坑—swift版(附oc参考)
3.其他注意点
  • 个人开发者账户不支持Sign In With Apple功能

三、app端代码实现-Swift

  • 此处使用自定义苹果登录按钮样式,设计规范参见Sign In With Apple 设计规范

  • 也可使用苹果自带的样式(网上一堆,自行搜索)

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!
    }
    
}

四、附苹果登录logo图(44*44)

苹果登录signInWithApple踩坑—swift版(附oc参考)苹果登录signInWithApple踩坑—swift版(附oc参考)苹果登录signInWithApple踩坑—swift版(附oc参考)

苹果登录signInWithApple踩坑—swift版(附oc参考)苹果登录signInWithApple踩坑—swift版(附oc参考)苹果登录signInWithApple踩坑—swift版(附oc参考)
苹果登录signInWithApple踩坑—swift版(附oc参考)苹果登录signInWithApple踩坑—swift版(附oc参考)苹果登录signInWithApple踩坑—swift版(附oc参考)

oc版参考

iOS 苹果授权登录(Sign in with Apple)系列之原生篇

其他相关参考

iOS 苹果授权登录(Sign in with Apple)系列之Apple Developer配置篇

iOS 苹果授权登录(Sign in with Apple)系列之原生篇

iOS 苹果授权登录(Sign in with Apple)系列之uniapp篇

iOS 苹果授权登录(Sign in with Apple)系列之服务端篇

苹果设计规范

Sign In With Apple 设计规范

上一篇:OC 性能优化


下一篇:iOS 内存管理汇总