Skip to content

Commit

Permalink
🎉 Add support for Flutter "add to app" (#106)
Browse files Browse the repository at this point in the history
* The current implementation assumes the plugin is used in a pure Flutter app. It casts the app's rootViewController to FlutterViewController.

This supports using this plugin in an "add to app" use case. The implementation does not assume the rootViewController is an instance of FlutterViewController, but rather starts with the presented view controller, and navigates up the stack to the root controller. It also handles in the case of a non-modal screen, in which case it would be a UINavigationController. We could probably just use the presented view controller, rather than navigating up the stack to the root to use as the session context provider.

* Use guarded cast instead of forced unwrap.

* fix(swift): make changes from code review

* fix(swift): eliminate !s and unused code

Co-authored-by: junying1 <[email protected]>
  • Loading branch information
timshadel and junying1 authored Feb 24, 2022
1 parent a919cb8 commit 5b51fb4
Showing 1 changed file with 33 additions and 8 deletions.
41 changes: 33 additions & 8 deletions ios/Classes/SwiftFlutterWebAuthPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ public class SwiftFlutterWebAuthPlugin: NSObject, FlutterPlugin {
}

public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
if call.method == "authenticate" {
let url = URL(string: (call.arguments as! Dictionary<String, AnyObject>)["url"] as! String)!
let callbackURLScheme = (call.arguments as! Dictionary<String, AnyObject>)["callbackUrlScheme"] as! String
let preferEphemeral = (call.arguments as! Dictionary<String, AnyObject>)["preferEphemeral"] as! Bool
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
Expand All @@ -39,20 +42,36 @@ public class SwiftFlutterWebAuthPlugin: NSObject, FlutterPlugin {
return
}

result(url!.absoluteString)
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, *) {
guard let provider = UIApplication.shared.delegate?.window??.rootViewController as? FlutterViewController else {
result(FlutterError(code: "FAILED", message: "Failed to aquire root FlutterViewController" , details: nil))
guard var topController = UIApplication.shared.keyWindow?.rootViewController else {
result(FlutterError.aquireRootViewControllerFailed)
return
}

while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
if let nav = topController as? UINavigationController {
topController = nav.visibleViewController ?? topController
}

guard let contextProvider = topController as? ASWebAuthenticationPresentationContextProviding else {
result(FlutterError.aquireRootViewControllerFailed)
return
}
session.presentationContextProvider = contextProvider
session.prefersEphemeralWebBrowserSession = preferEphemeral
session.presentationContextProvider = provider
}

session.start()
Expand All @@ -79,3 +98,9 @@ extension FlutterViewController: ASWebAuthenticationPresentationContextProviding
return self.view.window!
}
}

fileprivate extension FlutterError {
static var aquireRootViewControllerFailed: FlutterError {
return FlutterError(code: "AQUIRE_ROOT_VIEW_CONTROLLER_FAILED", message: "Failed to aquire root view controller" , details: nil)
}
}

0 comments on commit 5b51fb4

Please sign in to comment.