117 lines
4.0 KiB
Swift
117 lines
4.0 KiB
Swift
//
|
|
// SRLogin+third.swift
|
|
// SynthReel
|
|
//
|
|
// Created by CSGY on 2025/12/1.
|
|
// Copyright © 2025 SR. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import AuthenticationServices
|
|
|
|
extension SRLogin {
|
|
|
|
private struct AssociatedKeys {
|
|
static var appleLoginHandle: Int?
|
|
}
|
|
|
|
private var appleLoginHandle: ((_ model: SRThirdModel?) -> Void)? {
|
|
set {
|
|
objc_setAssociatedObject(self, &AssociatedKeys.appleLoginHandle, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
|
|
}
|
|
get {
|
|
return objc_getAssociatedObject(self, &AssociatedKeys.appleLoginHandle) as? ((_ model: SRThirdModel?) -> Void)
|
|
}
|
|
}
|
|
|
|
func appleLogin(completer: ((_ model: SRThirdModel?) -> Void)?) {
|
|
self.appleLoginHandle = completer
|
|
|
|
let appleIDProvider = ASAuthorizationAppleIDProvider()
|
|
let request = appleIDProvider.createRequest()
|
|
request.requestedScopes = [.fullName, .email]
|
|
|
|
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
|
|
authorizationController.delegate = self
|
|
authorizationController.presentationContextProvider = self
|
|
authorizationController.performRequests()
|
|
}
|
|
|
|
private func jwtDecode(jwtStr: String) -> [String: Any]? {
|
|
let segments = jwtStr.components(separatedBy: ".")
|
|
guard segments.count > 1 else { return nil }
|
|
|
|
var base64String = segments[1]
|
|
|
|
// 处理 Base64 补齐
|
|
let requiredLength = 4 * Int(ceil(Double(base64String.count) / 4.0))
|
|
let paddingLength = requiredLength - base64String.count
|
|
if paddingLength > 0 {
|
|
base64String += String(repeating: "=", count: paddingLength)
|
|
}
|
|
|
|
// 替换 URL 安全字符
|
|
base64String = base64String.replacingOccurrences(of: "-", with: "+")
|
|
base64String = base64String.replacingOccurrences(of: "_", with: "/")
|
|
|
|
// 解码 Base64 数据
|
|
guard let data = Data(base64Encoded: base64String),
|
|
let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []),
|
|
let payload = jsonObject as? [String: Any] else {
|
|
return nil
|
|
}
|
|
|
|
return payload
|
|
}
|
|
|
|
}
|
|
|
|
//MARK: ASAuthorizationControllerDelegate
|
|
extension SRLogin: ASAuthorizationControllerDelegate {
|
|
|
|
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
|
|
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
|
|
|
|
let userIdentifier = appleIDCredential.user
|
|
let fullName = appleIDCredential.fullName
|
|
let email = appleIDCredential.email
|
|
|
|
let identityToken = appleIDCredential.identityToken.flatMap { String(data: $0, encoding: .utf8) }
|
|
let identityTokenParams = self.jwtDecode(jwtStr: identityToken ?? "")
|
|
|
|
|
|
var model = SRThirdModel()
|
|
model.platform = .apple
|
|
model.third_id = userIdentifier
|
|
model.giving_name = fullName?.givenName
|
|
model.family_name = fullName?.familyName
|
|
model.avator = identityTokenParams?["picture"] as? String
|
|
model.email = identityTokenParams?["email"] as? String
|
|
|
|
|
|
debugLog(userIdentifier)
|
|
debugLog(fullName)
|
|
debugLog(email)
|
|
|
|
appleLoginHandle?(model)
|
|
appleLoginHandle = nil
|
|
}
|
|
}
|
|
|
|
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
|
|
appleLoginHandle?(nil)
|
|
appleLoginHandle = nil
|
|
}
|
|
|
|
}
|
|
|
|
//MARK: ASAuthorizationControllerPresentationContextProviding
|
|
extension SRLogin: ASAuthorizationControllerPresentationContextProviding {
|
|
|
|
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
|
|
return SRTool.keyWindow!
|
|
}
|
|
|
|
}
|
|
|