Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
swift-format
  • Loading branch information
Serdnad committed Feb 7, 2023
commit f04747fce6c0efe6853e5e32d5bf99a6e406222f
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,38 @@ import Flutter
import SafariServices

class URLLaunchSession: NSObject, SFSafariViewControllerDelegate {
var flutterResult: FlutterResult?
var url: URL
var safari: SFSafariViewController
var didFinish: (() -> Void)?
var flutterResult: FlutterResult?
var url: URL
var safari: SFSafariViewController
var didFinish: (() -> Void)?

init(url: URL, result: FlutterResult?) {
self.url = url
self.flutterResult = result
self.safari = SFSafariViewController(url: url)
init(url: URL, result: FlutterResult?) {
self.url = url
self.flutterResult = result
self.safari = SFSafariViewController(url: url)

super.init()
self.safari.delegate = self
}
super.init()
self.safari.delegate = self
}

func safariViewController(_ controller: SFSafariViewController, didCompleteInitialLoad didLoadSuccessfully: Bool) {
if didLoadSuccessfully {
self.flutterResult?(true)
} else {
self.flutterResult?(FlutterError(code: "Error", message: "Error while launching \(self.url.absoluteString)", details: nil))
}
func safariViewController(
_ controller: SFSafariViewController, didCompleteInitialLoad didLoadSuccessfully: Bool
) {
if didLoadSuccessfully {
self.flutterResult?(true)
} else {
self.flutterResult?(
FlutterError(
code: "Error", message: "Error while launching \(self.url.absoluteString)", details: nil))
}
}

func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true, completion: nil)
self.didFinish?()
}
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true, completion: nil)
self.didFinish?()
}

func close() {
self.safariViewControllerDidFinish(self.safari)
}
func close() {
self.safariViewControllerDidFinish(self.safari)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,106 +6,109 @@ import Flutter
import UIKit

public final class URLLauncherPlugin: NSObject, FlutterPlugin {
private var currentSession: URLLaunchSession?
private var currentSession: URLLaunchSession?

public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "plugins.flutter.io/url_launcher_ios", binaryMessenger: registrar.messenger())
let instance = URLLauncherPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(
name: "plugins.flutter.io/url_launcher_ios", binaryMessenger: registrar.messenger())
let instance = URLLauncherPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}

public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
let args = call.arguments as! [String: Any]
let url = args["url"] as! String
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
let args = call.arguments as! [String: Any]
let url = args["url"] as! String

switch call.method {
case "canLaunch":
result(canLaunchURL(url))
case "launch":
let useSafariVC = args["useSafariVC"] as? Bool ?? false
if useSafariVC {
launchURLInVC(url, result: result)
} else {
launchURL(url, call: call, result: result)
}
case "closeWebView":
closeWebView(result: result)
default:
result(FlutterMethodNotImplemented)
}
switch call.method {
case "canLaunch":
result(canLaunchURL(url))
case "launch":
let useSafariVC = args["useSafariVC"] as? Bool ?? false
if useSafariVC {
launchURLInVC(url, result: result)
} else {
launchURL(url, call: call, result: result)
}
case "closeWebView":
closeWebView(result: result)
default:
result(FlutterMethodNotImplemented)
}
}

private func canLaunchURL(_ url: String) -> Bool {
guard let url = URL(string: url) else {
// TODO: should we log a warning to the dev their URL was invalid?
return false
}

return UIApplication.shared.canOpenURL(url)
private func canLaunchURL(_ url: String) -> Bool {
guard let url = URL(string: url) else {
// TODO: should we log a warning to the dev their URL was invalid?
return false
}

private func launchURL(_ url: String, call: FlutterMethodCall, result: @escaping FlutterResult) {
let args = call.arguments as! [String: Any]
let universalLinksOnly = (args["universalLinksOnly"] as? Bool) ?? false
let options = [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly: universalLinksOnly]
UIApplication.shared.open(URL(string: url)!, options: options) { success in
result(success)
}
}
return UIApplication.shared.canOpenURL(url)
}

private func launchURLInVC(_ url: String, result: @escaping FlutterResult) {
currentSession = URLLaunchSession(url: URL(string: url)!, result: result)
currentSession?.didFinish = {
self.currentSession = nil
}
self.topViewController.present(currentSession!.safari, animated: true, completion: nil)
private func launchURL(_ url: String, call: FlutterMethodCall, result: @escaping FlutterResult) {
let args = call.arguments as! [String: Any]
let universalLinksOnly = (args["universalLinksOnly"] as? Bool) ?? false
let options = [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly: universalLinksOnly]
UIApplication.shared.open(URL(string: url)!, options: options) { success in
result(success)
}
}

private func closeWebView(result: @escaping FlutterResult) {
currentSession?.close()
result(nil)
private func launchURLInVC(_ url: String, result: @escaping FlutterResult) {
currentSession = URLLaunchSession(url: URL(string: url)!, result: result)
currentSession?.didFinish = {
self.currentSession = nil
}
self.topViewController.present(currentSession!.safari, animated: true, completion: nil)
}

private func launchURLInVC(urlString: String, result: @escaping FlutterResult) {
let url = URL(string: urlString)!
self.currentSession = URLLaunchSession(url: url, result: result)
weak var weakSelf = self
self.currentSession!.didFinish = {
weakSelf?.currentSession = nil
}
self.topViewController.present(self.currentSession!.safari, animated: true, completion: nil)
}
private func closeWebView(result: @escaping FlutterResult) {
currentSession?.close()
result(nil)
}

private func closeWebViewWithResult(result: @escaping FlutterResult) {
self.currentSession?.close()
result(nil)
private func launchURLInVC(urlString: String, result: @escaping FlutterResult) {
let url = URL(string: urlString)!
self.currentSession = URLLaunchSession(url: url, result: result)
weak var weakSelf = self
self.currentSession!.didFinish = {
weakSelf?.currentSession = nil
}
self.topViewController.present(self.currentSession!.safari, animated: true, completion: nil)
}

private var topViewController: UIViewController {
// TODO: Provide a non-deprecated codepath. See https://github.com/flutter/flutter/issues/104117
return topViewControllerFromViewController(UIApplication.shared.keyWindow!.rootViewController!)
}
private func closeWebViewWithResult(result: @escaping FlutterResult) {
self.currentSession?.close()
result(nil)
}

private var topViewController: UIViewController {
// TODO: Provide a non-deprecated codepath. See https://github.com/flutter/flutter/issues/104117
return topViewControllerFromViewController(UIApplication.shared.keyWindow!.rootViewController!)
}

/// This method recursively iterates through the view hierarchy
/// to return the top most view controller.
///
/// It supports the following scenarios:
///
/// - The view controller is presenting another view.
/// - The view controller is a UINavigationController.
/// - The view controller is a UITabBarController.
///
/// @return The top most view controller.
private func topViewControllerFromViewController(_ viewController: UIViewController) -> UIViewController {
if let navigationController = viewController as? UINavigationController {
return topViewControllerFromViewController(navigationController.viewControllers.last!)
}
if let tabController = viewController as? UITabBarController {
return topViewControllerFromViewController(tabController.selectedViewController!)
}
if let presentedViewController = viewController.presentedViewController {
return topViewControllerFromViewController(presentedViewController)
}
return viewController
/// This method recursively iterates through the view hierarchy
/// to return the top most view controller.
///
/// It supports the following scenarios:
///
/// - The view controller is presenting another view.
/// - The view controller is a UINavigationController.
/// - The view controller is a UITabBarController.
///
/// @return The top most view controller.
private func topViewControllerFromViewController(_ viewController: UIViewController)
-> UIViewController
{
if let navigationController = viewController as? UINavigationController {
return topViewControllerFromViewController(navigationController.viewControllers.last!)
}
if let tabController = viewController as? UITabBarController {
return topViewControllerFromViewController(tabController.selectedViewController!)
}
if let presentedViewController = viewController.presentedViewController {
return topViewControllerFromViewController(presentedViewController)
}
return viewController
}
}