Skip to content

Instantly share code, notes, and snippets.

View Yoloabdo's full-sized avatar
:octocat:
Building another UIViewController

Abdoelrhman Yoloabdo

:octocat:
Building another UIViewController
View GitHub Profile
protocol ServiceAuthorizer {
func authorize(_ results: ASAuthorizationAppleIDCredential)
}
extension PreferredAuthMethod {
func getService(source: UIViewController?, delegate: AuthServiceDelegate?) -> AuthService {
switch self {
case .apple:
if #available(iOS 13.0, *) {
return AppleAuthService(source, delegate: delegate)
} else {
return EmptyAuthService()
}
}
class ViewController: UIViewController {
// You've to use lazy since you're using self here, or you can set it on init, viewDidload, depends on your usage.
lazy var userAuthenticator = UserAuthenticator(self)
func didTapAppleSignin() {
userAuthenticator.authenticate(.apple)
}
}
protocol AuthServiceDelegate: AnyObject {
var userAuthenticator: UserAuthenticator { get }
/// Fired when user is authorised and confirmed via backend, returning user-info.
/// - Parameters:
/// - authService: service type.
/// - user: user info object.
func authService(_ authService: PreferredAuthMethod, didAuthenticate user: UserInfo)
@available(iOS 13.0, *)
extension AppleAuthService: ASAuthorizationControllerDelegate {
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
backendAuth?.authorize(appleIDCredential)
}
}
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
@available(iOS 13.0, *)
class AppleAuthService: NSObject, AuthService {
private weak var viewController: UIViewController?
private weak var delegate: AuthServiceDelegate?
private var backendAuth: ServiceAuthorizer?
var authType: PreferredAuthMethod = .apple
init(_ viewController: UIViewController?, delegate: AuthServiceDelegate?) {
self.viewController = viewController
self.delegate = delegate
typealias AuthenticationViewSource = UIViewController & AuthServiceDelegate
class UserAuthenticator {
private weak var source: AuthenticationViewSource?
private var service: AuthService?
init(_ viewController: AuthenticationViewSource) {
self.source = viewController
}
func userDidTapLogin(_ sender: UIButton) {
sender.startAnimating()
let command = LoginCommandsFactory.getLoginCommand(id, password: password) {[weak self] (response) in
self?.handleServerLogin(response)
sender.stopAnimating()
}
do {
try command.execute()
}catch{
sender.stopAnimating()
struct LoginCommandsFactory {
private init() {}
static func getLoginCommand(id: String, password: String, completion: CallResponse<User>) -> Command {
let validatorCommand = LoginDetailsValidator(id, password)
let requestCommand = LoginRequestCommand(id, password: password, completion: completion)
let combined = CommandsCombiner(validatorCommand, requestCommand)
return combined
}
}
struct CommandsCombiner: Command {
let commands: [Command]
init(_ commands: Command...) {
self.commands = commands
}
func execute() throws {
try commands.forEach { try $0.execute() }
}