-
Notifications
You must be signed in to change notification settings - Fork 230
/
SafariProvider.swift
108 lines (92 loc) · 3.28 KB
/
SafariProvider.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#if os(iOS)
import UIKit
import SafariServices
public extension WebAuthentication {
/// Creates a Web Auth provider that uses `SFSafariViewController` as the external user agent.
///
/// ## Usage
///
/// ```swift
/// Auth0
/// .webAuth()
/// .provider(WebAuthentication.safariProvider())
/// .start { result in
/// // ...
/// }
/// ```
///
/// If you need to specify a custom `UIModalPresentationStyle`:
///
/// ```swift
/// Auth0
/// .webAuth()
/// .provider(WebAuthentication.safariProvider(style: .formSheet))
/// .start { result in
/// // ...
/// }
/// ```
///
/// - Parameter style: `UIModalPresentationStyle` to be used. Defaults to `.fullScreen`.
/// - Returns: A ``WebAuthProvider`` instance.
///
/// ## See Also
///
/// - <doc:UserAgents>
static func safariProvider(style: UIModalPresentationStyle = .fullScreen) -> WebAuthProvider {
return { url, callback in
let safari = SFSafariViewController(url: url)
safari.dismissButtonStyle = .cancel
safari.modalPresentationStyle = style
return SafariUserAgent(controller: safari, callback: callback)
}
}
}
class SafariUserAgent: NSObject, WebAuthUserAgent {
let controller: SFSafariViewController
let callback: WebAuthProviderCallback
init(controller: SFSafariViewController, callback: @escaping WebAuthProviderCallback) {
self.controller = controller
self.callback = callback
super.init()
self.controller.delegate = self
self.controller.presentationController?.delegate = self
}
func start() {
UIWindow.topViewController?.present(controller, animated: true, completion: nil)
}
func finish(with result: WebAuthResult<Void>) {
if case .failure(let cause) = result, case .userCancelled = cause {
DispatchQueue.main.async { [callback] in
callback(result)
}
} else {
DispatchQueue.main.async { [callback, weak controller] in
guard let presenting = controller?.presentingViewController else {
let error = WebAuthError(code: .unknown("Cannot dismiss SFSafariViewController"))
return callback(.failure(error))
}
presenting.dismiss(animated: true) {
callback(result)
}
}
}
}
override var description: String {
return String(describing: SFSafariViewController.self)
}
}
extension SafariUserAgent: SFSafariViewControllerDelegate {
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
// If you are developing a custom Web Auth provider, call WebAuthentication.cancel() instead
// TransactionStore is internal
TransactionStore.shared.cancel()
}
}
extension SafariUserAgent: UIAdaptivePresentationControllerDelegate {
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
// If you are developing a custom Web Auth provider, call WebAuthentication.cancel() instead
// TransactionStore is internal
TransactionStore.shared.cancel()
}
}
#endif