2019-12-18 20:34:40 +00:00
|
|
|
//
|
|
|
|
// ChromeSafariBrowserManager.swift
|
|
|
|
// flutter_inappwebview
|
|
|
|
//
|
|
|
|
// Created by Lorenzo Pichilli on 18/12/2019.
|
|
|
|
//
|
|
|
|
|
|
|
|
import Flutter
|
|
|
|
import UIKit
|
|
|
|
import WebKit
|
|
|
|
import Foundation
|
|
|
|
import AVFoundation
|
|
|
|
import SafariServices
|
|
|
|
|
2022-05-05 18:19:16 +00:00
|
|
|
public class ChromeSafariBrowserManager: ChannelDelegate {
|
|
|
|
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_chromesafaribrowser"
|
2023-05-16 18:06:53 +00:00
|
|
|
var plugin: SwiftFlutterPlugin?
|
2023-05-18 22:45:12 +00:00
|
|
|
var browsers: [String: SafariViewController?] = [:]
|
|
|
|
var prewarmingTokens: [String: Any?] = [:]
|
2019-12-18 20:34:40 +00:00
|
|
|
|
2023-05-16 18:06:53 +00:00
|
|
|
init(plugin: SwiftFlutterPlugin) {
|
|
|
|
super.init(channel: FlutterMethodChannel(name: ChromeSafariBrowserManager.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger()))
|
|
|
|
self.plugin = plugin
|
2019-12-18 20:34:40 +00:00
|
|
|
}
|
|
|
|
|
2022-05-05 18:19:16 +00:00
|
|
|
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
2019-12-18 20:34:40 +00:00
|
|
|
let arguments = call.arguments as? NSDictionary
|
|
|
|
|
|
|
|
switch call.method {
|
|
|
|
case "open":
|
2022-05-08 23:51:21 +00:00
|
|
|
let id = arguments!["id"] as! String
|
2019-12-18 20:34:40 +00:00
|
|
|
let url = arguments!["url"] as! String
|
2022-04-20 00:18:36 +00:00
|
|
|
let settings = arguments!["settings"] as! [String: Any?]
|
2020-05-21 01:34:39 +00:00
|
|
|
let menuItemList = arguments!["menuItemList"] as! [[String: Any]]
|
2022-04-20 00:18:36 +00:00
|
|
|
open(id: id, url: url, settings: settings, menuItemList: menuItemList, result: result)
|
2019-12-18 20:34:40 +00:00
|
|
|
break
|
2020-06-30 12:29:19 +00:00
|
|
|
case "isAvailable":
|
|
|
|
if #available(iOS 9.0, *) {
|
|
|
|
result(true)
|
|
|
|
} else {
|
|
|
|
result(false)
|
|
|
|
}
|
|
|
|
break
|
2022-10-24 10:34:18 +00:00
|
|
|
case "clearWebsiteData":
|
|
|
|
if #available(iOS 16.0, *) {
|
|
|
|
SFSafariViewController.DataStore.default.clearWebsiteData {
|
|
|
|
result(true)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
result(false)
|
|
|
|
}
|
|
|
|
case "prewarmConnections":
|
|
|
|
if #available(iOS 15.0, *) {
|
|
|
|
let stringURLs = arguments!["URLs"] as! [String]
|
|
|
|
var URLs: [URL] = []
|
|
|
|
for stringURL in stringURLs {
|
|
|
|
if let url = URL(string: stringURL) {
|
|
|
|
URLs.append(url)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let prewarmingToken = SFSafariViewController.prewarmConnections(to: URLs)
|
|
|
|
let prewarmingTokenId = NSUUID().uuidString
|
2023-05-18 22:45:12 +00:00
|
|
|
prewarmingTokens[prewarmingTokenId] = prewarmingToken
|
2022-10-24 10:34:18 +00:00
|
|
|
result([
|
|
|
|
"id": prewarmingTokenId
|
|
|
|
])
|
|
|
|
} else {
|
|
|
|
result(nil)
|
|
|
|
}
|
|
|
|
case "invalidatePrewarmingToken":
|
|
|
|
if #available(iOS 15.0, *) {
|
|
|
|
let prewarmingToken = arguments!["prewarmingToken"] as! [String:Any?]
|
|
|
|
if let prewarmingTokenId = prewarmingToken["id"] as? String,
|
2023-05-18 22:45:12 +00:00
|
|
|
let prewarmingToken = prewarmingTokens[prewarmingTokenId] as? SFSafariViewController.PrewarmingToken? {
|
2022-10-24 10:34:18 +00:00
|
|
|
prewarmingToken?.invalidate()
|
2023-05-18 22:45:12 +00:00
|
|
|
prewarmingTokens[prewarmingTokenId] = nil
|
2022-10-24 10:34:18 +00:00
|
|
|
}
|
|
|
|
result(true)
|
|
|
|
} else {
|
|
|
|
result(false)
|
|
|
|
}
|
2019-12-18 20:34:40 +00:00
|
|
|
default:
|
|
|
|
result(FlutterMethodNotImplemented)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-20 00:18:36 +00:00
|
|
|
public func open(id: String, url: String, settings: [String: Any?], menuItemList: [[String: Any]], result: @escaping FlutterResult) {
|
2019-12-18 20:34:40 +00:00
|
|
|
let absoluteUrl = URL(string: url)!.absoluteURL
|
|
|
|
|
2023-05-16 18:06:53 +00:00
|
|
|
if #available(iOS 9.0, *), let plugin = plugin {
|
2019-12-18 20:34:40 +00:00
|
|
|
|
2023-08-02 10:34:58 +00:00
|
|
|
if let flutterViewController = UIApplication.shared.visibleViewController {
|
2021-01-28 23:57:30 +00:00
|
|
|
// flutterViewController could be casted to FlutterViewController if needed
|
|
|
|
|
2022-04-20 00:18:36 +00:00
|
|
|
let safariSettings = SafariBrowserSettings()
|
|
|
|
let _ = safariSettings.parse(settings: settings)
|
2019-12-18 20:34:40 +00:00
|
|
|
|
Updated onCreateWindow, onJsAlert, onJsConfirm, and onJsPrompt webview events, added onCloseWindow, onTitleChanged, onWindowFocus, and onWindowBlur webview events, added androidOnRequestFocus, androidOnReceivedIcon, androidOnReceivedTouchIconUrl, androidOnJsBeforeUnload, and androidOnReceivedLoginRequest Android-specific webview events, fix #403
2020-06-29 14:34:08 +00:00
|
|
|
let safari: SafariViewController
|
|
|
|
|
|
|
|
if #available(iOS 11.0, *) {
|
|
|
|
let config = SFSafariViewController.Configuration()
|
2023-05-16 18:06:53 +00:00
|
|
|
safari = SafariViewController(plugin: plugin, id: id, url: absoluteUrl, configuration: config,
|
2022-05-05 22:16:00 +00:00
|
|
|
menuItemList: menuItemList, safariSettings: safariSettings)
|
Updated onCreateWindow, onJsAlert, onJsConfirm, and onJsPrompt webview events, added onCloseWindow, onTitleChanged, onWindowFocus, and onWindowBlur webview events, added androidOnRequestFocus, androidOnReceivedIcon, androidOnReceivedTouchIconUrl, androidOnJsBeforeUnload, and androidOnReceivedLoginRequest Android-specific webview events, fix #403
2020-06-29 14:34:08 +00:00
|
|
|
} else {
|
|
|
|
// Fallback on earlier versions
|
2023-05-16 18:06:53 +00:00
|
|
|
safari = SafariViewController(plugin: plugin, id: id, url: absoluteUrl, entersReaderIfAvailable: safariSettings.entersReaderIfAvailable,
|
2022-05-05 22:16:00 +00:00
|
|
|
menuItemList: menuItemList, safariSettings: safariSettings)
|
Updated onCreateWindow, onJsAlert, onJsConfirm, and onJsPrompt webview events, added onCloseWindow, onTitleChanged, onWindowFocus, and onWindowBlur webview events, added androidOnRequestFocus, androidOnReceivedIcon, androidOnReceivedTouchIconUrl, androidOnJsBeforeUnload, and androidOnReceivedLoginRequest Android-specific webview events, fix #403
2020-06-29 14:34:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
safari.prepareSafariBrowser()
|
|
|
|
|
|
|
|
flutterViewController.present(safari, animated: true) {
|
|
|
|
result(true)
|
|
|
|
}
|
2022-05-08 23:51:21 +00:00
|
|
|
|
2023-05-18 22:45:12 +00:00
|
|
|
browsers[id] = safari
|
2019-12-18 20:34:40 +00:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2021-02-22 11:16:23 +00:00
|
|
|
|
|
|
|
result(FlutterError.init(code: "ChromeSafariBrowserManager", message: "SafariViewController is not available!", details: nil))
|
2019-12-18 20:34:40 +00:00
|
|
|
}
|
2022-04-23 02:02:37 +00:00
|
|
|
|
2022-05-05 18:19:16 +00:00
|
|
|
public override func dispose() {
|
|
|
|
super.dispose()
|
2023-05-18 22:45:12 +00:00
|
|
|
let browserValues = browsers.values
|
|
|
|
browserValues.forEach { (browser: SafariViewController?) in
|
2022-05-05 22:16:00 +00:00
|
|
|
browser?.close(result: nil)
|
|
|
|
browser?.dispose()
|
|
|
|
}
|
2023-05-18 22:45:12 +00:00
|
|
|
browsers.removeAll()
|
2022-10-24 10:34:18 +00:00
|
|
|
if #available(iOS 15.0, *) {
|
2023-05-18 22:45:12 +00:00
|
|
|
let prewarmingTokensValues = prewarmingTokens.values
|
|
|
|
prewarmingTokensValues.forEach { (prewarmingToken: Any?) in
|
|
|
|
if let prewarmingToken = prewarmingToken as? SFSafariViewController.PrewarmingToken? {
|
|
|
|
prewarmingToken?.invalidate()
|
|
|
|
}
|
2022-10-24 10:34:18 +00:00
|
|
|
}
|
2023-05-18 22:45:12 +00:00
|
|
|
prewarmingTokens.removeAll()
|
2022-10-24 10:34:18 +00:00
|
|
|
}
|
2023-05-16 18:06:53 +00:00
|
|
|
plugin = nil
|
2022-04-23 02:02:37 +00:00
|
|
|
}
|
2022-05-08 10:56:28 +00:00
|
|
|
|
|
|
|
deinit {
|
|
|
|
dispose()
|
|
|
|
}
|
2019-12-18 20:34:40 +00:00
|
|
|
}
|