Skip to content

Instantly share code, notes, and snippets.

@iamchiwon
Last active July 6, 2023 07:37
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save iamchiwon/20aa57d4e8f6110bc3f79742c2fb6cc5 to your computer and use it in GitHub Desktop.
Save iamchiwon/20aa57d4e8f6110bc3f79742c2fb6cc5 to your computer and use it in GitHub Desktop.
 Sign in with Apple + Rx
import AuthenticationServices
import RxCocoa
import RxSwift
import UIKit
@available(iOS 13.0, *)
extension ASAuthorizationController: HasDelegate {
public typealias Delegate = ASAuthorizationControllerDelegate
}
@available(iOS 13.0, *)
class ASAuthorizationControllerProxy: DelegateProxy<ASAuthorizationController, ASAuthorizationControllerDelegate>, DelegateProxyType, ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
var presentationWindow: UIWindow = UIWindow()
public init(controller: ASAuthorizationController) {
super.init(parentObject: controller, delegateProxy: ASAuthorizationControllerProxy.self)
}
// MARK: - DelegateProxyType
public static func registerKnownImplementations() {
register { ASAuthorizationControllerProxy(controller: $0) }
}
// MARK: - Proxy Subject
internal lazy var didComplete = PublishSubject<ASAuthorization>()
// MARK: - ASAuthorizationControllerDelegate
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
didComplete.onNext(authorization)
didComplete.onCompleted()
}
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
didComplete.onCompleted()
}
// MARK: - ASAuthorizationControllerPresentationContextProviding
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
return presentationWindow
}
// MARK: - Completed
deinit {
self.didComplete.onCompleted()
}
}
import AuthenticationServices
import RxCocoa
import RxSwift
import UIKit
@available(iOS 13.0, *)
extension Reactive where Base: ASAuthorizationAppleIDProvider {
public func login(scope: [ASAuthorization.Scope]? = nil, on window: UIWindow) -> Observable<ASAuthorization> {
let request = base.createRequest()
request.requestedScopes = scope
let controller = ASAuthorizationController(authorizationRequests: [request])
let proxy = ASAuthorizationControllerProxy.proxy(for: controller)
proxy.presentationWindow = window
controller.presentationContextProvider = proxy
controller.performRequests()
return proxy.didComplete
}
}
@available(iOS 13.0, *)
extension Reactive where Base: ASAuthorizationAppleIDButton {
public func loginOnTap(scope: [ASAuthorization.Scope]? = nil) -> Observable<ASAuthorization> {
let window = base.window!
return controlEvent(.touchUpInside)
.flatMap {
ASAuthorizationAppleIDProvider().rx.login(scope: scope, on: window)
}
}
public func login(scope: [ASAuthorization.Scope]? = nil) -> Observable<ASAuthorization> {
return ASAuthorizationAppleIDProvider().rx.login(scope: scope, on: base.window!)
}
}
import AuthenticationServices
let appleLoginButton = ASAuthorizationAppleIDButton()
//...
appleLoginButton.rx
.loginOnTap(scope: [.fullName, .email])
.subscribe(onNext: { result in
guard let auth = result.credential as? ASAuthorizationAppleIDCredential else { return }
print(auth.user)
print(auth.email)
print(auth.fullName?.givenName)
print(auth.fullName?.familyName)
})
.disposed(by: disposeBag)
@kimxwan0319
Copy link

kimxwan0319 commented Jan 20, 2021

안녕하세요! 이 코드를 사용하려고하는데 'AuthenticationServices+Rx.swift'파일 27번째줄(let window = base.window!)이부분에 <Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value> 이 에러가 뜨네요.. 해결방법이 있을까요?

@yangseongyeal2
Copy link

yangseongyeal2 commented Nov 1, 2022

appleLoginButton.rx
.loginOnTap(scope: [.fullName, .email])
.subscribe(onNext: { result in
guard let auth = result.credential as? ASAuthorizationAppleIDCredential else { return }
print(auth.user)
print(auth.email)
print(auth.fullName?.givenName)
print(auth.fullName?.familyName)
})
.disposed(by: disposeBag)
를 viewDidAppear 에서 구현 하세요

@iamchiwon
Copy link
Author

window가 없다는 것은 버튼이 뷰에 붙지 않았다는 거니까. 붙은 이후에 호출하시면 됩니다.
강제 unwrapping 한 이유는 죽어야 잘못된걸 알 수 있으니까 죽으라고 그런겁니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment