added other iOS ChannelDelegate implementations, added ChromeSafariBrowserManager.browsers map native code

This commit is contained in:
Lorenzo Pichilli 2022-05-06 00:16:00 +02:00
parent 9af4aa032b
commit 66add9f8ac
11 changed files with 195 additions and 108 deletions

View File

@ -14,7 +14,6 @@ public class ActionBroadcastReceiver extends BroadcastReceiver {
protected static final String LOG_TAG = "ActionBroadcastReceiver"; protected static final String LOG_TAG = "ActionBroadcastReceiver";
public static final String KEY_ACTION_ID = "com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.ACTION_ID"; public static final String KEY_ACTION_ID = "com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.ACTION_ID";
public static final String KEY_ACTION_VIEW_ID = "com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.ACTION_VIEW_ID"; public static final String KEY_ACTION_VIEW_ID = "com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.ACTION_VIEW_ID";
public static final String CHROME_MANAGER_ID = "com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.CHROME_MANAGER_ID";
public static final String KEY_URL_TITLE = "android.intent.extra.SUBJECT"; public static final String KEY_URL_TITLE = "android.intent.extra.SUBJECT";
@Override @Override
@ -26,15 +25,10 @@ public class ActionBroadcastReceiver extends BroadcastReceiver {
int id = b.getInt(KEY_ACTION_ID); int id = b.getInt(KEY_ACTION_ID);
String title = b.getString(KEY_URL_TITLE); String title = b.getString(KEY_URL_TITLE);
String managerId = b.getString(CHROME_MANAGER_ID); ChromeCustomTabsActivity browser = ChromeSafariBrowserManager.browsers.get(viewId);
ChromeSafariBrowserManager manager = (ChromeSafariBrowserManager) ChromeSafariBrowserManager.shared.get(managerId); if (browser != null && browser.channelDelegate != null) {
browser.channelDelegate.onChromeSafariBrowserItemActionPerform(id, url, title);
MethodChannel channel = new MethodChannel(manager.plugin.messenger, ChromeCustomTabsActivity.METHOD_CHANNEL_NAME_PREFIX + viewId); }
Map<String, Object> obj = new HashMap<>();
obj.put("url", url);
obj.put("title", title);
obj.put("id", id);
channel.invokeMethod("onChromeSafariBrowserItemActionPerform", obj);
} }
} }
} }

View File

@ -9,8 +9,9 @@ import android.graphics.Color;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.CallSuper;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.browser.customtabs.CustomTabColorSchemeParams; import androidx.browser.customtabs.CustomTabColorSchemeParams;
import androidx.browser.customtabs.CustomTabsCallback; import androidx.browser.customtabs.CustomTabsCallback;
@ -19,6 +20,7 @@ import androidx.browser.customtabs.CustomTabsService;
import androidx.browser.customtabs.CustomTabsSession; import androidx.browser.customtabs.CustomTabsSession;
import com.pichillilorenzo.flutter_inappwebview.R; import com.pichillilorenzo.flutter_inappwebview.R;
import com.pichillilorenzo.flutter_inappwebview.headless_in_app_webview.HeadlessInAppWebViewManager;
import com.pichillilorenzo.flutter_inappwebview.types.CustomTabsActionButton; import com.pichillilorenzo.flutter_inappwebview.types.CustomTabsActionButton;
import com.pichillilorenzo.flutter_inappwebview.types.CustomTabsMenuItem; import com.pichillilorenzo.flutter_inappwebview.types.CustomTabsMenuItem;
import com.pichillilorenzo.flutter_inappwebview.types.Disposable; import com.pichillilorenzo.flutter_inappwebview.types.Disposable;
@ -28,7 +30,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel;
public class ChromeCustomTabsActivity extends Activity implements Disposable { public class ChromeCustomTabsActivity extends Activity implements Disposable {
@ -54,6 +55,7 @@ public class ChromeCustomTabsActivity extends Activity implements Disposable {
@Nullable @Nullable
public ChromeCustomTabsChannelDelegate channelDelegate; public ChromeCustomTabsChannelDelegate channelDelegate;
@CallSuper
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -69,6 +71,8 @@ public class ChromeCustomTabsActivity extends Activity implements Disposable {
manager = ChromeSafariBrowserManager.shared.get(managerId); manager = ChromeSafariBrowserManager.shared.get(managerId);
if (manager == null || manager.plugin == null|| manager.plugin.messenger == null) return; if (manager == null || manager.plugin == null|| manager.plugin.messenger == null) return;
ChromeSafariBrowserManager.browsers.put(id, this);
MethodChannel channel = new MethodChannel(manager.plugin.messenger, METHOD_CHANNEL_NAME_PREFIX + id); MethodChannel channel = new MethodChannel(manager.plugin.messenger, METHOD_CHANNEL_NAME_PREFIX + id);
channelDelegate = new ChromeCustomTabsChannelDelegate(this, channel); channelDelegate = new ChromeCustomTabsChannelDelegate(this, channel);
@ -230,7 +234,6 @@ public class ChromeCustomTabsActivity extends Activity implements Disposable {
Bundle extras = new Bundle(); Bundle extras = new Bundle();
extras.putInt(ActionBroadcastReceiver.KEY_ACTION_ID, actionSourceId); extras.putInt(ActionBroadcastReceiver.KEY_ACTION_ID, actionSourceId);
extras.putString(ActionBroadcastReceiver.KEY_ACTION_VIEW_ID, id); extras.putString(ActionBroadcastReceiver.KEY_ACTION_VIEW_ID, id);
extras.putString(ActionBroadcastReceiver.CHROME_MANAGER_ID, manager.id);
actionIntent.putExtras(extras); actionIntent.putExtras(extras);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
@ -244,14 +247,21 @@ public class ChromeCustomTabsActivity extends Activity implements Disposable {
@Override @Override
public void dispose() { public void dispose() {
onStop();
onDestroy();
if (channelDelegate != null) { if (channelDelegate != null) {
channelDelegate.dispose(); channelDelegate.dispose();
channelDelegate = null; channelDelegate = null;
} }
if (ChromeSafariBrowserManager.browsers.containsKey(id)) {
ChromeSafariBrowserManager.browsers.put(id, null);
}
manager = null; manager = null;
} }
public void close() { public void close() {
onStop();
onDestroy();
customTabsSession = null; customTabsSession = null;
finish(); finish();
if (channelDelegate != null) { if (channelDelegate != null) {

View File

@ -75,6 +75,16 @@ public class ChromeCustomTabsChannelDelegate extends ChannelDelegateImpl {
channel.invokeMethod("onChromeSafariBrowserClosed", obj); channel.invokeMethod("onChromeSafariBrowserClosed", obj);
} }
public void onChromeSafariBrowserItemActionPerform(int id, String url, String title) {
MethodChannel channel = getChannel();
if (channel == null) return;
Map<String, Object> obj = new HashMap<>();
obj.put("id", id);
obj.put("url", url);
obj.put("title", title);
channel.invokeMethod("onChromeSafariBrowserItemActionPerform", obj);
}
@Override @Override
public void dispose() { public void dispose() {
super.dispose(); super.dispose();

View File

@ -8,9 +8,11 @@ import androidx.annotation.Nullable;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin; import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
import com.pichillilorenzo.flutter_inappwebview.Util; import com.pichillilorenzo.flutter_inappwebview.Util;
import com.pichillilorenzo.flutter_inappwebview.headless_in_app_webview.HeadlessInAppWebView;
import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl; import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -27,6 +29,7 @@ public class ChromeSafariBrowserManager extends ChannelDelegateImpl {
public InAppWebViewFlutterPlugin plugin; public InAppWebViewFlutterPlugin plugin;
public String id; public String id;
public static final Map<String, ChromeSafariBrowserManager> shared = new HashMap<>(); public static final Map<String, ChromeSafariBrowserManager> shared = new HashMap<>();
public static final Map<String, ChromeCustomTabsActivity> browsers = new HashMap<>();
public ChromeSafariBrowserManager(final InAppWebViewFlutterPlugin plugin) { public ChromeSafariBrowserManager(final InAppWebViewFlutterPlugin plugin) {
super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME)); super(new MethodChannel(plugin.messenger, METHOD_CHANNEL_NAME));
@ -37,7 +40,7 @@ public class ChromeSafariBrowserManager extends ChannelDelegateImpl {
@Override @Override
public void onMethodCall(final MethodCall call, final MethodChannel.Result result) { public void onMethodCall(final MethodCall call, final MethodChannel.Result result) {
final String id = (String) call.argument("id"); final String viewId = (String) call.argument("id");
switch (call.method) { switch (call.method) {
case "open": case "open":
@ -46,7 +49,7 @@ public class ChromeSafariBrowserManager extends ChannelDelegateImpl {
HashMap<String, Object> settings = (HashMap<String, Object>) call.argument("settings"); HashMap<String, Object> settings = (HashMap<String, Object>) call.argument("settings");
HashMap<String, Object> actionButton = (HashMap<String, Object>) call.argument("actionButton"); HashMap<String, Object> actionButton = (HashMap<String, Object>) call.argument("actionButton");
List<HashMap<String, Object>> menuItemList = (List<HashMap<String, Object>>) call.argument("menuItemList"); List<HashMap<String, Object>> menuItemList = (List<HashMap<String, Object>>) call.argument("menuItemList");
open(plugin.activity, id, url, settings, actionButton, menuItemList, result); open(plugin.activity, viewId, url, settings, actionButton, menuItemList, result);
} else { } else {
result.success(false); result.success(false);
} }
@ -63,7 +66,7 @@ public class ChromeSafariBrowserManager extends ChannelDelegateImpl {
} }
} }
public void open(Activity activity, String id, String url, HashMap<String, Object> settings, public void open(Activity activity, String viewId, String url, HashMap<String, Object> settings,
HashMap<String, Object> actionButton, HashMap<String, Object> actionButton,
List<HashMap<String, Object>> menuItemList, MethodChannel.Result result) { List<HashMap<String, Object>> menuItemList, MethodChannel.Result result) {
@ -71,7 +74,7 @@ public class ChromeSafariBrowserManager extends ChannelDelegateImpl {
Bundle extras = new Bundle(); Bundle extras = new Bundle();
extras.putString("url", url); extras.putString("url", url);
extras.putBoolean("isData", false); extras.putBoolean("isData", false);
extras.putString("id", id); extras.putString("id", viewId);
extras.putString("managerId", this.id); extras.putString("managerId", this.id);
extras.putSerializable("settings", settings); extras.putSerializable("settings", settings);
extras.putSerializable("actionButton", (Serializable) actionButton); extras.putSerializable("actionButton", (Serializable) actionButton);
@ -99,6 +102,14 @@ public class ChromeSafariBrowserManager extends ChannelDelegateImpl {
@Override @Override
public void dispose() { public void dispose() {
super.dispose(); super.dispose();
Collection<ChromeCustomTabsActivity> browserList = browsers.values();
for (ChromeCustomTabsActivity browser : browserList) {
if (browser != null) {
browser.close();
browser.dispose();
}
}
browsers.clear();
shared.remove(this.id); shared.remove(this.id);
plugin = null; plugin = null;
} }

View File

@ -96,7 +96,7 @@ public class HeadlessInAppWebView implements Disposable {
HeadlessInAppWebViewManager.webViews.put(id, null); HeadlessInAppWebViewManager.webViews.put(id, null);
} }
if (plugin != null && plugin.activity != null) { if (plugin != null && plugin.activity != null) {
ViewGroup contentView = (ViewGroup) plugin.activity.findViewById(android.R.id.content); ViewGroup contentView = plugin.activity.findViewById(android.R.id.content);
if (contentView != null) { if (contentView != null) {
ViewGroup mainView = (ViewGroup) (contentView).getChildAt(0); ViewGroup mainView = (ViewGroup) (contentView).getChildAt(0);
if (mainView != null && flutterWebView != null) { if (mainView != null && flutterWebView != null) {

View File

@ -9,12 +9,12 @@ import Foundation
public class HeadlessWebViewChannelDelegate : ChannelDelegate { public class HeadlessWebViewChannelDelegate : ChannelDelegate {
private var headlessWebView: HeadlessInAppWebView? private var headlessWebView: HeadlessInAppWebView?
public init(headlessWebView: HeadlessInAppWebView, channel: FlutterMethodChannel) { public init(headlessWebView: HeadlessInAppWebView, channel: FlutterMethodChannel) {
super.init(channel: channel) super.init(channel: channel)
self.headlessWebView = headlessWebView self.headlessWebView = headlessWebView
} }
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
let arguments = call.arguments as? NSDictionary let arguments = call.arguments as? NSDictionary
@ -46,14 +46,14 @@ public class HeadlessWebViewChannelDelegate : ChannelDelegate {
break break
} }
} }
public func onWebViewCreated() { public func onWebViewCreated() {
let arguments: [String: Any?] = [:] let arguments: [String: Any?] = [:]
channel?.invokeMethod("onWebViewCreated", arguments: arguments) channel?.invokeMethod("onWebViewCreated", arguments: arguments)
} }
public override func dispose() { public override func dispose() {
super.dispose() super.dispose()
headlessWebView = nil headlessWebView = nil
} }
} }

View File

@ -0,0 +1,24 @@
//
// InAppBrowserChannelDelegate.swift
// flutter_inappwebview
//
// Created by Lorenzo Pichilli on 05/05/22.
//
import Foundation
public class InAppBrowserChannelDelegate : ChannelDelegate {
public override init(channel: FlutterMethodChannel) {
super.init(channel: channel)
}
public func onBrowserCreated() {
let arguments: [String: Any?] = [:]
channel?.invokeMethod("onBrowserCreated", arguments: arguments)
}
public func onExit() {
let arguments: [String: Any?] = [:]
channel?.invokeMethod("onExit", arguments: arguments)
}
}

View File

@ -10,7 +10,8 @@ import UIKit
import WebKit import WebKit
import Foundation import Foundation
public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelegate, UIScrollViewDelegate, WKUIDelegate, UISearchBarDelegate { public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelegate, UIScrollViewDelegate, UISearchBarDelegate, Disposable {
static var METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappbrowser_";
var closeButton: UIBarButtonItem! var closeButton: UIBarButtonItem!
var reloadButton: UIBarButtonItem! var reloadButton: UIBarButtonItem!
@ -24,7 +25,7 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
var id: String = "" var id: String = ""
var windowId: Int64? var windowId: Int64?
var webView: InAppWebView! var webView: InAppWebView!
var channel: FlutterMethodChannel? var channelDelegate: InAppBrowserChannelDelegate?
var initialUrlRequest: URLRequest? var initialUrlRequest: URLRequest?
var initialFile: String? var initialFile: String?
var contextMenu: [String: Any]? var contextMenu: [String: Any]?
@ -40,7 +41,8 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
var methodCallDelegate: InAppWebViewMethodHandler? var methodCallDelegate: InAppWebViewMethodHandler?
public override func loadView() { public override func loadView() {
channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappbrowser_" + id, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger()) let channel = FlutterMethodChannel(name: InAppBrowserWebViewController.METHOD_CHANNEL_NAME_PREFIX + id, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
channelDelegate = InAppBrowserChannelDelegate(channel: channel)
var userScripts: [UserScript] = [] var userScripts: [UserScript] = []
for intialUserScript in initialUserScripts { for intialUserScript in initialUserScripts {
@ -51,19 +53,19 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
if let wId = windowId, let webViewTransport = InAppWebView.windowWebViews[wId] { if let wId = windowId, let webViewTransport = InAppWebView.windowWebViews[wId] {
webView = webViewTransport.webView webView = webViewTransport.webView
webView.contextMenu = contextMenu webView.contextMenu = contextMenu
webView.channel = channel! webView.channel = channel
webView.initialUserScripts = userScripts webView.initialUserScripts = userScripts
} else { } else {
webView = InAppWebView(frame: .zero, webView = InAppWebView(frame: .zero,
configuration: preWebviewConfiguration, configuration: preWebviewConfiguration,
contextMenu: contextMenu, contextMenu: contextMenu,
channel: channel!, channel: channel,
userScripts: userScripts) userScripts: userScripts)
} }
webView.inAppBrowserDelegate = self webView.inAppBrowserDelegate = self
methodCallDelegate = InAppWebViewMethodHandler(webView: webView!) methodCallDelegate = InAppWebViewMethodHandler(webView: webView!)
channel!.setMethodCallHandler(LeakAvoider(delegate: methodCallDelegate!).handle) channel.setMethodCallHandler(LeakAvoider(delegate: methodCallDelegate!).handle)
let pullToRefreshSettings = PullToRefreshSettings() let pullToRefreshSettings = PullToRefreshSettings()
let _ = pullToRefreshSettings.parse(settings: pullToRefreshInitialSettings) let _ = pullToRefreshSettings.parse(settings: pullToRefreshInitialSettings)
@ -175,7 +177,8 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
} }
webView.loadUrl(urlRequest: initialUrlRequest, allowingReadAccessTo: allowingReadAccessToURL) webView.loadUrl(urlRequest: initialUrlRequest, allowingReadAccessTo: allowingReadAccessToURL)
} }
onBrowserCreated()
channelDelegate?.onBrowserCreated()
} }
deinit { deinit {
@ -549,9 +552,9 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
} }
public func dispose() { public func dispose() {
onExit() channelDelegate?.onExit()
channel?.setMethodCallHandler(nil) channelDelegate?.dispose()
channel = nil channelDelegate = nil
webView?.dispose() webView?.dispose()
webView = nil webView = nil
view = nil view = nil
@ -568,12 +571,4 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
methodCallDelegate?.webView = nil methodCallDelegate?.webView = nil
methodCallDelegate = nil methodCallDelegate = nil
} }
public func onBrowserCreated() {
channel?.invokeMethod("onBrowserCreated", arguments: [])
}
public func onExit() {
channel?.invokeMethod("onExit", arguments: [])
}
} }

View File

@ -15,6 +15,7 @@ import SafariServices
public class ChromeSafariBrowserManager: ChannelDelegate { public class ChromeSafariBrowserManager: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_chromesafaribrowser" static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_chromesafaribrowser"
static var registrar: FlutterPluginRegistrar? static var registrar: FlutterPluginRegistrar?
static var browsers: [String: SafariViewController?] = [:]
init(registrar: FlutterPluginRegistrar) { init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: ChromeSafariBrowserManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger())) super.init(channel: FlutterMethodChannel(name: ChromeSafariBrowserManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger()))
@ -63,17 +64,14 @@ public class ChromeSafariBrowserManager: ChannelDelegate {
config.entersReaderIfAvailable = safariSettings.entersReaderIfAvailable config.entersReaderIfAvailable = safariSettings.entersReaderIfAvailable
config.barCollapsingEnabled = safariSettings.barCollapsingEnabled config.barCollapsingEnabled = safariSettings.barCollapsingEnabled
safari = SafariViewController(url: absoluteUrl, configuration: config) safari = SafariViewController(id: id, url: absoluteUrl, configuration: config,
menuItemList: menuItemList, safariSettings: safariSettings)
} else { } else {
// Fallback on earlier versions // Fallback on earlier versions
safari = SafariViewController(url: absoluteUrl) safari = SafariViewController(id: id, url: absoluteUrl, entersReaderIfAvailable: safariSettings.entersReaderIfAvailable,
menuItemList: menuItemList, safariSettings: safariSettings)
} }
safari.id = id
safari.menuItemList = menuItemList
safari.prepareMethodChannel()
safari.delegate = safari
safari.safariSettings = safariSettings
safari.prepareSafariBrowser() safari.prepareSafariBrowser()
flutterViewController.present(safari, animated: true) { flutterViewController.present(safari, animated: true) {
@ -89,5 +87,11 @@ public class ChromeSafariBrowserManager: ChannelDelegate {
public override func dispose() { public override func dispose() {
super.dispose() super.dispose()
ChromeSafariBrowserManager.registrar = nil ChromeSafariBrowserManager.registrar = nil
let browsers = ChromeSafariBrowserManager.browsers.values
browsers.forEach { (browser: SafariViewController?) in
browser?.close(result: nil)
browser?.dispose()
}
ChromeSafariBrowserManager.browsers.removeAll()
} }
} }

View File

@ -9,15 +9,34 @@ import Foundation
import SafariServices import SafariServices
@available(iOS 9.0, *) @available(iOS 9.0, *)
public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafariViewControllerDelegate { public class SafariViewController: SFSafariViewController, SFSafariViewControllerDelegate, Disposable {
static let METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_chromesafaribrowser_"
var channel: FlutterMethodChannel? var channelDelegate: SafariViewControllerChannelDelegate?
var safariSettings: SafariBrowserSettings? var safariSettings: SafariBrowserSettings
var id: String = "" var id: String
var menuItemList: [[String: Any]] = [] var menuItemList: [[String: Any]] = []
public static func register(with registrar: FlutterPluginRegistrar) { @available(iOS 11.0, *)
public init(id: String, url: URL, configuration: SFSafariViewController.Configuration, menuItemList: [[String: Any]] = [], safariSettings: SafariBrowserSettings) {
self.id = id
self.menuItemList = menuItemList
self.safariSettings = safariSettings
super.init(url: url, configuration: configuration)
let channel = FlutterMethodChannel(name: SafariViewController.METHOD_CHANNEL_NAME_PREFIX + id,
binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
self.channelDelegate = SafariViewControllerChannelDelegate(safariViewController: self, channel: channel)
self.delegate = self
}
public init(id: String, url: URL, entersReaderIfAvailable: Bool, menuItemList: [[String: Any]] = [], safariSettings: SafariBrowserSettings) {
self.id = id
self.menuItemList = menuItemList
self.safariSettings = safariSettings
super.init(url: url, entersReaderIfAvailable: entersReaderIfAvailable)
let channel = FlutterMethodChannel(name: SafariViewController.METHOD_CHANNEL_NAME_PREFIX + id,
binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
self.channelDelegate = SafariViewControllerChannelDelegate(safariViewController: self, channel: channel)
self.delegate = self
} }
deinit { deinit {
@ -25,41 +44,20 @@ public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafa
dispose() dispose()
} }
public func prepareMethodChannel() {
channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_chromesafaribrowser_" + id, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
SwiftFlutterPlugin.instance!.registrar!.addMethodCallDelegate(self, channel: channel!)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
// let arguments = call.arguments as? NSDictionary
switch call.method {
case "close":
close(result: result)
break
default:
result(FlutterMethodNotImplemented)
break
}
}
public override func viewWillAppear(_ animated: Bool) { public override func viewWillAppear(_ animated: Bool) {
// prepareSafariBrowser() // prepareSafariBrowser()
super.viewWillAppear(animated) super.viewWillAppear(animated)
onChromeSafariBrowserOpened() channelDelegate?.onChromeSafariBrowserOpened()
} }
public override func viewDidDisappear(_ animated: Bool) { public override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated) super.viewDidDisappear(animated)
self.onChromeSafariBrowserClosed() channelDelegate?.onChromeSafariBrowserClosed()
self.dispose() self.dispose()
} }
func prepareSafariBrowser() { func prepareSafariBrowser() {
guard let safariSettings = safariSettings else {
return
}
if #available(iOS 11.0, *) { if #available(iOS 11.0, *) {
self.dismissButtonStyle = SFSafariViewController.DismissButtonStyle(rawValue: safariSettings.dismissButtonStyle)! self.dismissButtonStyle = SFSafariViewController.DismissButtonStyle(rawValue: safariSettings.dismissButtonStyle)!
} }
@ -82,8 +80,8 @@ public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafa
// wait for the animation // wait for the animation
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(400), execute: {() -> Void in DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(400), execute: {() -> Void in
if result != nil { if let result = result {
result!(true) result(true)
} }
}) })
} }
@ -95,7 +93,7 @@ public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafa
public func safariViewController(_ controller: SFSafariViewController, public func safariViewController(_ controller: SFSafariViewController,
didCompleteInitialLoad didLoadSuccessfully: Bool) { didCompleteInitialLoad didLoadSuccessfully: Bool) {
if didLoadSuccessfully { if didLoadSuccessfully {
onChromeSafariBrowserCompletedInitialLoad() channelDelegate?.onChromeSafariBrowserCompletedInitialLoad()
} }
else { else {
print("Cant load successfully the 'SafariViewController'.") print("Cant load successfully the 'SafariViewController'.")
@ -123,22 +121,11 @@ public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafa
// print(URL) // print(URL)
// } // }
public func onChromeSafariBrowserOpened() {
channel?.invokeMethod("onChromeSafariBrowserOpened", arguments: [])
}
public func onChromeSafariBrowserCompletedInitialLoad() {
channel?.invokeMethod("onChromeSafariBrowserCompletedInitialLoad", arguments: [])
}
public func onChromeSafariBrowserClosed() {
channel?.invokeMethod("onChromeSafariBrowserClosed", arguments: [])
}
public func dispose() { public func dispose() {
channel?.setMethodCallHandler(nil) channelDelegate?.dispose()
channel = nil channelDelegate = nil
delegate = nil delegate = nil
ChromeSafariBrowserManager.browsers[id] = nil
} }
} }
@ -182,18 +169,7 @@ class CustomUIActivity : UIActivity {
} }
override func perform() { override func perform() {
guard let registrar = SwiftFlutterPlugin.instance?.registrar else { let browser = ChromeSafariBrowserManager.browsers[viewId]
return browser??.channelDelegate?.onChromeSafariBrowserMenuItemActionPerform(id: id, url: url, title: title)
}
let channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_chromesafaribrowser_" + viewId,
binaryMessenger: registrar.messenger())
let arguments: [String: Any?] = [
"url": url.absoluteString,
"title": title,
"id": id,
]
channel.invokeMethod("onChromeSafariBrowserMenuItemActionPerform", arguments: arguments)
} }
} }

View File

@ -0,0 +1,63 @@
//
// SafariViewControllerChannelDelegate.swift
// flutter_inappwebview
//
// Created by Lorenzo Pichilli on 05/05/22.
//
import Foundation
public class SafariViewControllerChannelDelegate : ChannelDelegate {
private var safariViewController: SafariViewController?
public init(safariViewController: SafariViewController, channel: FlutterMethodChannel) {
super.init(channel: channel)
self.safariViewController = safariViewController
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
// let arguments = call.arguments as? NSDictionary
switch call.method {
case "close":
if let safariViewController = safariViewController {
safariViewController.close(result: result)
} else {
result(false)
}
break
default:
result(FlutterMethodNotImplemented)
break
}
}
public func onChromeSafariBrowserOpened() {
let arguments: [String: Any?] = [:]
channel?.invokeMethod("onChromeSafariBrowserOpened", arguments: arguments)
}
public func onChromeSafariBrowserCompletedInitialLoad() {
let arguments: [String: Any?] = [:]
channel?.invokeMethod("onChromeSafariBrowserCompletedInitialLoad", arguments: arguments)
}
public func onChromeSafariBrowserClosed() {
let arguments: [String: Any?] = [:]
channel?.invokeMethod("onChromeSafariBrowserClosed", arguments: arguments)
}
public func onChromeSafariBrowserMenuItemActionPerform(id: Int64, url: URL, title: String?) {
let arguments: [String: Any?] = [
"id": id,
"url": url.absoluteString,
"title": title,
]
channel?.invokeMethod("onChromeSafariBrowserMenuItemActionPerform", arguments: arguments)
}
public override func dispose() {
super.dispose()
safariViewController = nil
}
}