Skip to content

Instantly share code, notes, and snippets.

@atimca
Last active April 2, 2020 15:53
Show Gist options
  • Save atimca/c9e8af68d41585a60cd8495f35ccd8eb to your computer and use it in GitHub Desktop.
Save atimca/c9e8af68d41585a60cd8495f35ccd8eb to your computer and use it in GitHub Desktop.
Reactive extension for "Sign in with Apple"
import AuthenticationServices
import RxCocoa
import RxSwift
@available(iOS 13.0, *)
private class RxAppleSignInDelegateProxy: DelegateProxy<ASAuthorizationController, ASAuthorizationControllerDelegate> {
private(set) var controller: ASAuthorizationController?
fileprivate var signInSubject = PublishSubject<ASAuthorization>()
init(controller: ASAuthorizationController) {
self.controller = controller
super.init(parentObject: controller, delegateProxy: RxAppleSignInDelegateProxy.self)
}
deinit {
signInSubject.onCompleted()
}
}
// MARK: - DelegateProxyType
@available(iOS 13.0, *)
extension RxAppleSignInDelegateProxy: DelegateProxyType {
static func registerKnownImplementations() {
self.register(make: RxAppleSignInDelegateProxy.init)
}
class func currentDelegate(for object: ASAuthorizationController) -> ASAuthorizationControllerDelegate? {
return object.delegate
}
class func setCurrentDelegate(_ delegate: ASAuthorizationControllerDelegate?, to object: ASAuthorizationController) {
object.delegate = delegate
}
}
// MARK: - ASAuthorizationControllerDelegate
@available(iOS 13.0, *)
extension RxAppleSignInDelegateProxy: ASAuthorizationControllerDelegate {
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
signInSubject.onNext(authorization)
signInSubject.onCompleted()
}
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
if (error as NSError).code == ASAuthorizationError.canceled.rawValue {
signInSubject.onCompleted()
return
}
signInSubject.onError(error)
}
}
// MARK: - Reactive
@available(iOS 13.0, *)
extension Reactive where Base: ASAuthorizationController {
func signIn() -> Maybe<ASAuthorization> {
let proxy = appleSignInDelegate
proxy.signInSubject = PublishSubject<ASAuthorization>()
return proxy.signInSubject
.asObservable()
.do(onSubscribed: { in
proxy.controller?.performRequests()
})
.take(1)
.asMaybe()
}
private var appleSignInDelegate: RxAppleSignInDelegateProxy { RxAppleSignInDelegateProxy.proxy(for: base) }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment