-
Notifications
You must be signed in to change notification settings - Fork 255
Expand file tree
/
Copy pathSwiftFlutterWebAuthPlugin.swift
More file actions
119 lines (101 loc) · 5.24 KB
/
Copy pathSwiftFlutterWebAuthPlugin.swift
File metadata and controls
119 lines (101 loc) · 5.24 KB
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
109
110
111
112
113
114
115
116
117
118
119
import AuthenticationServices
import SafariServices
import Flutter
import UIKit
public class SwiftFlutterWebAuthPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "flutter_web_auth", binaryMessenger: registrar.messenger())
let instance = SwiftFlutterWebAuthPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
if call.method == "authenticate",
let arguments = call.arguments as? Dictionary<String, AnyObject>,
let urlString = arguments["url"] as? String,
let url = URL(string: urlString),
let callbackURLScheme = arguments["callbackUrlScheme"] as? String,
let preferEphemeral = arguments["preferEphemeral"] as? Bool
{
var sessionToKeepAlive: Any? = nil // if we do not keep the session alive, it will get closed immediately while showing the dialog
let completionHandler = { (url: URL?, err: Error?) in
sessionToKeepAlive = nil
if let err = err {
if #available(iOS 12, *) {
if case ASWebAuthenticationSessionError.canceledLogin = err {
result(FlutterError(code: "CANCELED", message: "User canceled login", details: nil))
return
}
}
if #available(iOS 11, *) {
if case SFAuthenticationError.canceledLogin = err {
result(FlutterError(code: "CANCELED", message: "User canceled login", details: nil))
return
}
}
result(FlutterError(code: "EUNKNOWN", message: err.localizedDescription, details: nil))
return
}
guard let url = url else {
result(FlutterError(code: "EUNKNOWN", message: "URL was null, but no error provided.", details: nil))
return
}
result(url.absoluteString)
}
if #available(iOS 12, *) {
let session = ASWebAuthenticationSession(url: url, callbackURLScheme: callbackURLScheme, completionHandler: completionHandler)
if #available(iOS 13, *) {
var rootViewController: UIViewController? = nil
// FlutterViewController
if (rootViewController == nil) {
rootViewController = UIApplication.shared.delegate?.window??.rootViewController as? FlutterViewController
}
// UIViewController
if (rootViewController == nil) {
rootViewController = UIApplication.shared.keyWindow?.rootViewController
}
// ACQUIRE_ROOT_VIEW_CONTROLLER_FAILED
if (rootViewController == nil) {
result(FlutterError.acquireRootViewControllerFailed)
return
}
while let presentedViewController = rootViewController!.presentedViewController {
rootViewController = presentedViewController
}
if let nav = rootViewController as? UINavigationController {
rootViewController = nav.visibleViewController ?? rootViewController
}
guard let contextProvider = rootViewController as? ASWebAuthenticationPresentationContextProviding else {
result(FlutterError.acquireRootViewControllerFailed)
return
}
session.presentationContextProvider = contextProvider
session.prefersEphemeralWebBrowserSession = preferEphemeral
}
session.start()
sessionToKeepAlive = session
} else if #available(iOS 11, *) {
let session = SFAuthenticationSession(url: url, callbackURLScheme: callbackURLScheme, completionHandler: completionHandler)
session.start()
sessionToKeepAlive = session
} else {
result(FlutterError(code: "FAILED", message: "This plugin does currently not support iOS lower than iOS 11" , details: nil))
}
} else if (call.method == "cleanUpDanglingCalls") {
// we do not keep track of old callbacks on iOS, so nothing to do here
result(nil)
} else {
result(FlutterMethodNotImplemented)
}
}
}
@available(iOS 13, *)
extension FlutterViewController: ASWebAuthenticationPresentationContextProviding {
public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
return self.view.window!
}
}
fileprivate extension FlutterError {
static var acquireRootViewControllerFailed: FlutterError {
return FlutterError(code: "ACQUIRE_ROOT_VIEW_CONTROLLER_FAILED", message: "Failed to acquire root view controller" , details: nil)
}
}