1179 lines
44 KiB
Swift
1179 lines
44 KiB
Swift
//
|
|
// WebViewChannelDelegate.swift
|
|
// flutter_inappwebview
|
|
//
|
|
// Created by Lorenzo Pichilli on 06/05/22.
|
|
//
|
|
|
|
import Foundation
|
|
import WebKit
|
|
import FlutterMacOS
|
|
|
|
public class WebViewChannelDelegate: ChannelDelegate {
|
|
private weak var webView: InAppWebView?
|
|
|
|
public init(webView: InAppWebView, channel: FlutterMethodChannel) {
|
|
super.init(channel: channel)
|
|
self.webView = webView
|
|
}
|
|
|
|
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
|
let arguments = call.arguments as? NSDictionary
|
|
|
|
guard let method = WebViewChannelDelegateMethods.init(rawValue: call.method) else {
|
|
result(FlutterMethodNotImplemented)
|
|
return
|
|
}
|
|
|
|
switch method {
|
|
case .getUrl:
|
|
result(webView?.url?.absoluteString)
|
|
break
|
|
case .getTitle:
|
|
result(webView?.title)
|
|
break
|
|
case .getProgress:
|
|
result( (webView != nil) ? Int(webView!.estimatedProgress * 100) : nil )
|
|
break
|
|
case .loadUrl:
|
|
let urlRequest = arguments!["urlRequest"] as! [String:Any?]
|
|
let allowingReadAccessTo = arguments!["allowingReadAccessTo"] as? String
|
|
var allowingReadAccessToURL: URL? = nil
|
|
if let allowingReadAccessTo = allowingReadAccessTo {
|
|
allowingReadAccessToURL = URL(string: allowingReadAccessTo)
|
|
}
|
|
webView?.loadUrl(urlRequest: URLRequest.init(fromPluginMap: urlRequest), allowingReadAccessTo: allowingReadAccessToURL)
|
|
result(true)
|
|
break
|
|
case .postUrl:
|
|
if let webView = webView {
|
|
let url = arguments!["url"] as! String
|
|
let postData = arguments!["postData"] as! FlutterStandardTypedData
|
|
webView.postUrl(url: URL(string: url)!, postData: postData.data)
|
|
}
|
|
result(true)
|
|
break
|
|
case .loadData:
|
|
let data = arguments!["data"] as! String
|
|
let mimeType = arguments!["mimeType"] as! String
|
|
let encoding = arguments!["encoding"] as! String
|
|
let baseUrl = URL(string: arguments!["baseUrl"] as! String)!
|
|
let allowingReadAccessTo = arguments!["allowingReadAccessTo"] as? String
|
|
var allowingReadAccessToURL: URL? = nil
|
|
if let allowingReadAccessTo = allowingReadAccessTo {
|
|
allowingReadAccessToURL = URL(string: allowingReadAccessTo)
|
|
}
|
|
webView?.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl, allowingReadAccessTo: allowingReadAccessToURL)
|
|
result(true)
|
|
break
|
|
case .loadFile:
|
|
let assetFilePath = arguments!["assetFilePath"] as! String
|
|
|
|
do {
|
|
try webView?.loadFile(assetFilePath: assetFilePath)
|
|
}
|
|
catch let error as NSError {
|
|
result(FlutterError(code: "WebViewChannelDelegate", message: error.domain, details: nil))
|
|
return
|
|
}
|
|
result(true)
|
|
break
|
|
case .evaluateJavascript:
|
|
if let webView = webView {
|
|
let source = arguments!["source"] as! String
|
|
let contentWorldMap = arguments!["contentWorld"] as? [String:Any?]
|
|
if #available(macOS 11.0, *), let contentWorldMap = contentWorldMap {
|
|
let contentWorld = WKContentWorld.fromMap(map: contentWorldMap, windowId: webView.windowId)!
|
|
webView.evaluateJavascript(source: source, contentWorld: contentWorld) { (value) in
|
|
result(value)
|
|
}
|
|
} else {
|
|
webView.evaluateJavascript(source: source) { (value) in
|
|
result(value)
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case .injectJavascriptFileFromUrl:
|
|
let urlFile = arguments!["urlFile"] as! String
|
|
let scriptHtmlTagAttributes = arguments!["scriptHtmlTagAttributes"] as? [String:Any?]
|
|
webView?.injectJavascriptFileFromUrl(urlFile: urlFile, scriptHtmlTagAttributes: scriptHtmlTagAttributes)
|
|
result(true)
|
|
break
|
|
case .injectCSSCode:
|
|
let source = arguments!["source"] as! String
|
|
webView?.injectCSSCode(source: source)
|
|
result(true)
|
|
break
|
|
case .injectCSSFileFromUrl:
|
|
let urlFile = arguments!["urlFile"] as! String
|
|
let cssLinkHtmlTagAttributes = arguments!["cssLinkHtmlTagAttributes"] as? [String:Any?]
|
|
webView?.injectCSSFileFromUrl(urlFile: urlFile, cssLinkHtmlTagAttributes: cssLinkHtmlTagAttributes)
|
|
result(true)
|
|
break
|
|
case .reload:
|
|
webView?.reload()
|
|
result(true)
|
|
break
|
|
case .goBack:
|
|
webView?.goBack()
|
|
result(true)
|
|
break
|
|
case .canGoBack:
|
|
result(webView?.canGoBack ?? false)
|
|
break
|
|
case .goForward:
|
|
webView?.goForward()
|
|
result(true)
|
|
break
|
|
case .canGoForward:
|
|
result(webView?.canGoForward ?? false)
|
|
break
|
|
case .goBackOrForward:
|
|
let steps = arguments!["steps"] as! Int
|
|
webView?.goBackOrForward(steps: steps)
|
|
result(true)
|
|
break
|
|
case .canGoBackOrForward:
|
|
let steps = arguments!["steps"] as! Int
|
|
result(webView?.canGoBackOrForward(steps: steps) ?? false)
|
|
break
|
|
case .stopLoading:
|
|
webView?.stopLoading()
|
|
result(true)
|
|
break
|
|
case .isLoading:
|
|
result(webView?.isLoading ?? false)
|
|
break
|
|
case .takeScreenshot:
|
|
if let webView = webView, #available(macOS 10.13, *) {
|
|
let screenshotConfiguration = arguments!["screenshotConfiguration"] as? [String: Any?]
|
|
webView.takeScreenshot(with: screenshotConfiguration, completionHandler: { (screenshot) -> Void in
|
|
result(screenshot)
|
|
})
|
|
}
|
|
else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case .setSettings:
|
|
if let iabController = webView?.inAppBrowserDelegate as? InAppBrowserWebViewController {
|
|
let inAppBrowserSettings = InAppBrowserSettings()
|
|
let inAppBrowserSettingsMap = arguments!["settings"] as! [String: Any]
|
|
let _ = inAppBrowserSettings.parse(settings: inAppBrowserSettingsMap)
|
|
iabController.setSettings(newSettings: inAppBrowserSettings, newSettingsMap: inAppBrowserSettingsMap)
|
|
} else {
|
|
let inAppWebViewSettings = InAppWebViewSettings()
|
|
let inAppWebViewSettingsMap = arguments!["settings"] as! [String: Any]
|
|
let _ = inAppWebViewSettings.parse(settings: inAppWebViewSettingsMap)
|
|
webView?.setSettings(newSettings: inAppWebViewSettings, newSettingsMap: inAppWebViewSettingsMap)
|
|
}
|
|
result(true)
|
|
break
|
|
case .getSettings:
|
|
if let iabController = webView?.inAppBrowserDelegate as? InAppBrowserWebViewController {
|
|
result(iabController.getSettings())
|
|
} else {
|
|
result(webView?.getSettings())
|
|
}
|
|
break
|
|
case .close:
|
|
if let iabController = webView?.inAppBrowserDelegate as? InAppBrowserWebViewController {
|
|
iabController.close()
|
|
result(true)
|
|
} else {
|
|
result(FlutterMethodNotImplemented)
|
|
}
|
|
break
|
|
case .show:
|
|
if let iabController = webView?.inAppBrowserDelegate as? InAppBrowserWebViewController {
|
|
iabController.show()
|
|
result(true)
|
|
} else {
|
|
result(FlutterMethodNotImplemented)
|
|
}
|
|
break
|
|
case .hide:
|
|
if let iabController = webView?.inAppBrowserDelegate as? InAppBrowserWebViewController {
|
|
iabController.hide()
|
|
result(true)
|
|
} else {
|
|
result(FlutterMethodNotImplemented)
|
|
}
|
|
break
|
|
case .isHidden:
|
|
if let iabController = webView?.inAppBrowserDelegate as? InAppBrowserWebViewController {
|
|
result(iabController.isHidden)
|
|
} else {
|
|
result(FlutterMethodNotImplemented)
|
|
}
|
|
break
|
|
case .getCopyBackForwardList:
|
|
result(webView?.getCopyBackForwardList())
|
|
break
|
|
case .findAll:
|
|
if let webView = webView, let findInteractionController = webView.findInteractionController {
|
|
let find = arguments!["find"] as! String
|
|
findInteractionController.findAll(find: find, completionHandler: {(value, error) in
|
|
if error != nil {
|
|
result(FlutterError(code: "WebViewChannelDelegate", message: error?.localizedDescription, details: nil))
|
|
return
|
|
}
|
|
result(true)
|
|
})
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case .findNext:
|
|
if let webView = webView, let findInteractionController = webView.findInteractionController {
|
|
let forward = arguments!["forward"] as! Bool
|
|
findInteractionController.findNext(forward: forward, completionHandler: {(value, error) in
|
|
if error != nil {
|
|
result(FlutterError(code: "WebViewChannelDelegate", message: error?.localizedDescription, details: nil))
|
|
return
|
|
}
|
|
result(true)
|
|
})
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case .clearMatches:
|
|
if let webView = webView, let findInteractionController = webView.findInteractionController {
|
|
findInteractionController.clearMatches(completionHandler: {(value, error) in
|
|
if error != nil {
|
|
result(FlutterError(code: "WebViewChannelDelegate", message: error?.localizedDescription, details: nil))
|
|
return
|
|
}
|
|
result(true)
|
|
})
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case .clearCache:
|
|
webView?.clearCache()
|
|
result(true)
|
|
break
|
|
case .scrollTo:
|
|
let x = arguments!["x"] as! Int
|
|
let y = arguments!["y"] as! Int
|
|
let animated = arguments!["animated"] as! Bool
|
|
webView?.scrollTo(x: x, y: y, animated: animated)
|
|
result(true)
|
|
break
|
|
case .scrollBy:
|
|
let x = arguments!["x"] as! Int
|
|
let y = arguments!["y"] as! Int
|
|
let animated = arguments!["animated"] as! Bool
|
|
webView?.scrollBy(x: x, y: y, animated: animated)
|
|
result(true)
|
|
break
|
|
case .pauseTimers:
|
|
webView?.pauseTimers()
|
|
result(true)
|
|
break
|
|
case .resumeTimers:
|
|
webView?.resumeTimers()
|
|
result(true)
|
|
break
|
|
case .printCurrentPage:
|
|
if let webView = webView {
|
|
let settings = PrintJobSettings()
|
|
if let settingsMap = arguments!["settings"] as? [String: Any?] {
|
|
let _ = settings.parse(settings: settingsMap)
|
|
}
|
|
result(webView.printCurrentPage(settings: settings))
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case .getContentHeight:
|
|
webView?.getContentHeight { contentHeight, error in
|
|
if let error = error {
|
|
print(error)
|
|
result(nil)
|
|
return
|
|
}
|
|
result(contentHeight)
|
|
}
|
|
break
|
|
case .getContentWidth:
|
|
webView?.getContentWidth { contentWidth, error in
|
|
if let error = error {
|
|
print(error)
|
|
result(nil)
|
|
return
|
|
}
|
|
result(contentWidth)
|
|
}
|
|
break
|
|
case .reloadFromOrigin:
|
|
webView?.reloadFromOrigin()
|
|
result(true)
|
|
break
|
|
case .getOriginalUrl:
|
|
result(webView?.getOriginalUrl()?.absoluteString)
|
|
break
|
|
case .getZoomScale:
|
|
result(nil)
|
|
break
|
|
case .hasOnlySecureContent:
|
|
result(webView?.hasOnlySecureContent ?? false)
|
|
break
|
|
case .getSelectedText:
|
|
if let webView = webView {
|
|
webView.getSelectedText { (value, error) in
|
|
if let err = error {
|
|
print(err.localizedDescription)
|
|
result("")
|
|
return
|
|
}
|
|
result(value)
|
|
}
|
|
}
|
|
else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case .getScrollX:
|
|
if let webView = webView {
|
|
webView.getScrollX { scrollX, error in
|
|
if let error = error {
|
|
print(error)
|
|
result(nil)
|
|
return
|
|
}
|
|
result(scrollX)
|
|
}
|
|
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case .getScrollY:
|
|
if let webView = webView {
|
|
webView.getScrollY { scrollY, error in
|
|
if let error = error {
|
|
print(error)
|
|
result(nil)
|
|
return
|
|
}
|
|
result(scrollY)
|
|
}
|
|
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case .getCertificate:
|
|
result(webView?.getCertificate()?.toMap())
|
|
break
|
|
case .addUserScript:
|
|
if let webView = webView {
|
|
let userScriptMap = arguments!["userScript"] as! [String: Any?]
|
|
let userScript = UserScript.fromMap(map: userScriptMap, windowId: webView.windowId)!
|
|
webView.configuration.userContentController.addUserOnlyScript(userScript)
|
|
webView.configuration.userContentController.sync(scriptMessageHandler: webView)
|
|
}
|
|
result(true)
|
|
break
|
|
case .removeUserScript:
|
|
let index = arguments!["index"] as! Int
|
|
let userScriptMap = arguments!["userScript"] as! [String: Any?]
|
|
let userScript = UserScript.fromMap(map: userScriptMap, windowId: webView?.windowId)!
|
|
webView?.configuration.userContentController.removeUserOnlyScript(at: index, injectionTime: userScript.injectionTime)
|
|
result(true)
|
|
break
|
|
case .removeUserScriptsByGroupName:
|
|
let groupName = arguments!["groupName"] as! String
|
|
webView?.configuration.userContentController.removeUserOnlyScripts(with: groupName)
|
|
result(true)
|
|
break
|
|
case .removeAllUserScripts:
|
|
webView?.configuration.userContentController.removeAllUserOnlyScripts()
|
|
result(true)
|
|
break
|
|
case .callAsyncJavaScript:
|
|
if let webView = webView {
|
|
if #available(macOS 11.0, *) { // on iOS 14.0, for some reason, it crashes
|
|
let functionBody = arguments!["functionBody"] as! String
|
|
let functionArguments = arguments!["arguments"] as! [String:Any]
|
|
var contentWorld = WKContentWorld.page
|
|
if let contentWorldMap = arguments!["contentWorld"] as? [String:Any?] {
|
|
contentWorld = WKContentWorld.fromMap(map: contentWorldMap, windowId: webView.windowId)!
|
|
}
|
|
webView.callAsyncJavaScript(functionBody: functionBody, arguments: functionArguments, contentWorld: contentWorld) { (value) in
|
|
result(value)
|
|
}
|
|
} else {
|
|
let functionBody = arguments!["functionBody"] as! String
|
|
let functionArguments = arguments!["arguments"] as! [String:Any]
|
|
webView.callAsyncJavaScript(functionBody: functionBody, arguments: functionArguments) { (value) in
|
|
result(value)
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case .createPdf:
|
|
if let webView = webView, #available(macOS 11.0, *) {
|
|
let configuration = arguments!["pdfConfiguration"] as? [String: Any?]
|
|
webView.createPdf(configuration: configuration, completionHandler: { (pdf) -> Void in
|
|
result(pdf)
|
|
})
|
|
}
|
|
else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case .createWebArchiveData:
|
|
if let webView = webView, #available(macOS 11.0, *) {
|
|
webView.createWebArchiveData(dataCompletionHandler: { (webArchiveData) -> Void in
|
|
result(webArchiveData)
|
|
})
|
|
}
|
|
else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case .saveWebArchive:
|
|
if let webView = webView, #available(macOS 11.0, *) {
|
|
let filePath = arguments!["filePath"] as! String
|
|
let autoname = arguments!["autoname"] as! Bool
|
|
webView.saveWebArchive(filePath: filePath, autoname: autoname, completionHandler: { (path) -> Void in
|
|
result(path)
|
|
})
|
|
}
|
|
else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case .isSecureContext:
|
|
if let webView = webView {
|
|
webView.isSecureContext(completionHandler: { (isSecureContext) in
|
|
result(isSecureContext)
|
|
})
|
|
}
|
|
else {
|
|
result(false)
|
|
}
|
|
break
|
|
case .createWebMessageChannel:
|
|
if let webView = webView {
|
|
let _ = webView.createWebMessageChannel { (webMessageChannel) in
|
|
guard let webMessageChannel = webMessageChannel else {
|
|
result(nil)
|
|
return
|
|
}
|
|
result(webMessageChannel.toMap())
|
|
}
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case .postWebMessage:
|
|
if let webView = webView {
|
|
var message = WebMessage.fromMap(map: arguments!["message"] as! [String: Any?])
|
|
let targetOrigin = arguments!["targetOrigin"] as! String
|
|
|
|
var ports: [WebMessagePort] = []
|
|
if let notConnectedPorts = message.ports {
|
|
for notConnectedPort in notConnectedPorts {
|
|
if let webMessageChannel = webView.webMessageChannels[notConnectedPort.webMessageChannelId] {
|
|
ports.append(webMessageChannel.ports[Int(notConnectedPort.index)])
|
|
}
|
|
}
|
|
}
|
|
message.ports = ports
|
|
|
|
do {
|
|
try webView.postWebMessage(message: message, targetOrigin: targetOrigin) { (_) in
|
|
result(true)
|
|
}
|
|
} catch let error as NSError {
|
|
result(FlutterError(code: "WebViewChannelDelegate", message: error.domain, details: nil))
|
|
}
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case .addWebMessageListener:
|
|
if let webView = webView, let plugin = webView.plugin {
|
|
let webMessageListenerMap = arguments!["webMessageListener"] as! [String: Any?]
|
|
let webMessageListener = WebMessageListener.fromMap(plugin: plugin, map: webMessageListenerMap)!
|
|
do {
|
|
try webView.addWebMessageListener(webMessageListener: webMessageListener)
|
|
result(false)
|
|
} catch let error as NSError {
|
|
result(FlutterError(code: "WebViewChannelDelegate", message: error.domain, details: nil))
|
|
}
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case .canScrollVertically:
|
|
if let webView = webView {
|
|
webView.canScrollVertically { canScrollVertically, error in
|
|
if let error = error {
|
|
print(error)
|
|
result(false)
|
|
return
|
|
}
|
|
result(canScrollVertically)
|
|
}
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case .canScrollHorizontally:
|
|
if let webView = webView {
|
|
webView.canScrollHorizontally { canScrollHorizontally, error in
|
|
if let error = error {
|
|
print(error)
|
|
result(false)
|
|
return
|
|
}
|
|
result(canScrollHorizontally)
|
|
}
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case .pauseAllMediaPlayback:
|
|
if let webView = webView, #available(macOS 12.0 , *) {
|
|
webView.pauseAllMediaPlayback(completionHandler: { () -> Void in
|
|
result(true)
|
|
})
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case .setAllMediaPlaybackSuspended:
|
|
if let webView = webView, #available(macOS 12.0 , *) {
|
|
let suspended = arguments!["suspended"] as! Bool
|
|
webView.setAllMediaPlaybackSuspended(suspended, completionHandler: { () -> Void in
|
|
result(true)
|
|
})
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case .closeAllMediaPresentations:
|
|
if let webView = self.webView, #available(macOS 11.3, *) {
|
|
if #available(macOS 12.0, *) {
|
|
webView.closeAllMediaPresentations {
|
|
result(true)
|
|
}
|
|
} else {
|
|
webView.closeAllMediaPresentations()
|
|
result(true)
|
|
}
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case .requestMediaPlaybackState:
|
|
if let webView = webView, #available(macOS 12.0, *) {
|
|
webView.requestMediaPlaybackState(completionHandler: { (state) -> Void in
|
|
result(state.rawValue)
|
|
})
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case .getMetaThemeColor:
|
|
if let webView = webView, #available(macOS 12.0, *) {
|
|
result(webView.themeColor?.hexString)
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case .isInFullscreen:
|
|
if let webView = webView {
|
|
if #available(macOS 13.0, *) {
|
|
result(webView.fullscreenState == .inFullscreen)
|
|
} else {
|
|
result(webView.inFullscreen)
|
|
}
|
|
}
|
|
else {
|
|
result(false)
|
|
}
|
|
break
|
|
case .getCameraCaptureState:
|
|
if let webView = webView, #available(macOS 12.0, *) {
|
|
result(webView.cameraCaptureState.rawValue)
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case .setCameraCaptureState:
|
|
if let webView = webView, #available(macOS 12.0, *) {
|
|
let state = WKMediaCaptureState.init(rawValue: arguments!["state"] as! Int) ?? WKMediaCaptureState.none
|
|
webView.setCameraCaptureState(state) {
|
|
result(true)
|
|
}
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case .getMicrophoneCaptureState:
|
|
if let webView = webView, #available(macOS 12.0, *) {
|
|
result(webView.microphoneCaptureState.rawValue)
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case .setMicrophoneCaptureState:
|
|
if let webView = webView, #available(macOS 12.0, *) {
|
|
let state = WKMediaCaptureState.init(rawValue: arguments!["state"] as! Int) ?? WKMediaCaptureState.none
|
|
webView.setMicrophoneCaptureState(state) {
|
|
result(true)
|
|
}
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case .loadSimulatedRequest:
|
|
if let webView = webView, #available(macOS 12.0, *) {
|
|
let request = URLRequest.init(fromPluginMap: arguments!["urlRequest"] as! [String:Any?])
|
|
let data = arguments!["data"] as! FlutterStandardTypedData
|
|
var response: URLResponse? = nil
|
|
if let urlResponse = arguments!["urlResponse"] as? [String:Any?] {
|
|
response = URLResponse.init(fromPluginMap: urlResponse)
|
|
}
|
|
if let response = response {
|
|
webView.loadSimulatedRequest(request, response: response, responseData: data.data)
|
|
} else {
|
|
webView.loadSimulatedRequest(request, responseHTML: String(decoding: data.data, as: UTF8.self))
|
|
}
|
|
result(true)
|
|
} else {
|
|
result(false)
|
|
}
|
|
}
|
|
}
|
|
|
|
@available(*, deprecated, message: "Use FindInteractionChannelDelegate.onFindResultReceived instead.")
|
|
public func onFindResultReceived(activeMatchOrdinal: Int, numberOfMatches: Int, isDoneCounting: Bool) {
|
|
let arguments: [String : Any?] = [
|
|
"activeMatchOrdinal": activeMatchOrdinal,
|
|
"numberOfMatches": numberOfMatches,
|
|
"isDoneCounting": isDoneCounting
|
|
]
|
|
channel?.invokeMethod("onFindResultReceived", arguments: arguments)
|
|
}
|
|
|
|
public func onLongPressHitTestResult(hitTestResult: HitTestResult) {
|
|
channel?.invokeMethod("onLongPressHitTestResult", arguments: hitTestResult.toMap())
|
|
}
|
|
|
|
public func onScrollChanged(x: Int, y: Int) {
|
|
let arguments: [String: Any?] = ["x": x, "y": y]
|
|
channel?.invokeMethod("onScrollChanged", arguments: arguments)
|
|
}
|
|
|
|
public func onDownloadStartRequest(request: DownloadStartRequest) {
|
|
channel?.invokeMethod("onDownloadStartRequest", arguments: request.toMap())
|
|
}
|
|
|
|
public func onCreateContextMenu(hitTestResult: HitTestResult) {
|
|
channel?.invokeMethod("onCreateContextMenu", arguments: hitTestResult.toMap())
|
|
}
|
|
|
|
public func onOverScrolled(x: Int, y: Int, clampedX: Bool, clampedY: Bool) {
|
|
let arguments: [String: Any?] = ["x": x, "y": y, "clampedX": clampedX, "clampedY": clampedY]
|
|
channel?.invokeMethod("onOverScrolled", arguments: arguments)
|
|
}
|
|
|
|
public func onContextMenuActionItemClicked(id: Any, title: String) {
|
|
let arguments: [String: Any?] = [
|
|
"id": id,
|
|
"iosId": id is Int64 ? String(id as! Int64) : id as! String,
|
|
"androidId": nil,
|
|
"title": title
|
|
]
|
|
channel?.invokeMethod("onContextMenuActionItemClicked", arguments: arguments)
|
|
}
|
|
|
|
public func onHideContextMenu() {
|
|
let arguments: [String: Any?] = [:]
|
|
channel?.invokeMethod("onHideContextMenu", arguments: arguments)
|
|
}
|
|
|
|
public func onEnterFullscreen() {
|
|
let arguments: [String: Any?] = [:]
|
|
channel?.invokeMethod("onEnterFullscreen", arguments: arguments)
|
|
}
|
|
|
|
public func onExitFullscreen() {
|
|
let arguments: [String: Any?] = [:]
|
|
channel?.invokeMethod("onExitFullscreen", arguments: arguments)
|
|
}
|
|
|
|
public class JsAlertCallback: BaseCallbackResult<JsAlertResponse> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
return JsAlertResponse.fromMap(map: obj as? [String:Any?])
|
|
}
|
|
}
|
|
}
|
|
|
|
public func onJsAlert(url: URL?, message: String, isMainFrame: Bool, callback: JsAlertCallback) {
|
|
if channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
let arguments: [String: Any?] = [
|
|
"url": url?.absoluteString,
|
|
"message": message,
|
|
"isMainFrame": isMainFrame
|
|
]
|
|
channel?.invokeMethod("onJsAlert", arguments: arguments, callback: callback)
|
|
}
|
|
|
|
public class JsConfirmCallback: BaseCallbackResult<JsConfirmResponse> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
return JsConfirmResponse.fromMap(map: obj as? [String:Any?])
|
|
}
|
|
}
|
|
}
|
|
|
|
public func onJsConfirm(url: URL?, message: String, isMainFrame: Bool, callback: JsConfirmCallback) {
|
|
if channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
let arguments: [String: Any?] = [
|
|
"url": url?.absoluteString,
|
|
"message": message,
|
|
"isMainFrame": isMainFrame
|
|
]
|
|
channel?.invokeMethod("onJsConfirm", arguments: arguments, callback: callback)
|
|
}
|
|
|
|
public class JsPromptCallback: BaseCallbackResult<JsPromptResponse> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
return JsPromptResponse.fromMap(map: obj as? [String:Any?])
|
|
}
|
|
}
|
|
}
|
|
|
|
public func onJsPrompt(url: URL?, message: String, defaultValue: String?, isMainFrame: Bool, callback: JsPromptCallback) {
|
|
if channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
let arguments: [String: Any?] = [
|
|
"url": url?.absoluteString,
|
|
"message": message,
|
|
"defaultValue": defaultValue,
|
|
"isMainFrame": isMainFrame
|
|
]
|
|
channel?.invokeMethod("onJsPrompt", arguments: arguments, callback: callback)
|
|
}
|
|
|
|
public class CreateWindowCallback: BaseCallbackResult<Bool> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
return obj is Bool && obj as! Bool
|
|
}
|
|
}
|
|
}
|
|
|
|
public func onCreateWindow(createWindowAction: CreateWindowAction, callback: CreateWindowCallback) {
|
|
if channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
channel?.invokeMethod("onCreateWindow", arguments: createWindowAction.toMap(), callback: callback)
|
|
}
|
|
|
|
public func onCloseWindow() {
|
|
let arguments: [String: Any?] = [:]
|
|
channel?.invokeMethod("onCloseWindow", arguments: arguments)
|
|
}
|
|
|
|
public func onConsoleMessage(message: String, messageLevel: Int) {
|
|
let arguments: [String: Any?] = [
|
|
"message": message,
|
|
"messageLevel": messageLevel
|
|
]
|
|
channel?.invokeMethod("onConsoleMessage", arguments: arguments)
|
|
}
|
|
|
|
public func onProgressChanged(progress: Int) {
|
|
let arguments: [String: Any?] = [
|
|
"progress": progress
|
|
]
|
|
channel?.invokeMethod("onProgressChanged", arguments: arguments)
|
|
}
|
|
|
|
public func onTitleChanged(title: String?) {
|
|
let arguments: [String: Any?] = [
|
|
"title": title
|
|
]
|
|
channel?.invokeMethod("onTitleChanged", arguments: arguments)
|
|
}
|
|
|
|
public class PermissionRequestCallback: BaseCallbackResult<PermissionResponse> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
return PermissionResponse.fromMap(map: obj as? [String:Any?])
|
|
}
|
|
}
|
|
|
|
deinit {
|
|
self.defaultBehaviour(nil)
|
|
}
|
|
}
|
|
|
|
public func onPermissionRequest(request: PermissionRequest, callback: PermissionRequestCallback) {
|
|
if channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
channel?.invokeMethod("onPermissionRequest", arguments: request.toMap(), callback: callback)
|
|
}
|
|
|
|
public class ShouldOverrideUrlLoadingCallback: BaseCallbackResult<WKNavigationActionPolicy> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
if let action = obj as? Int {
|
|
return WKNavigationActionPolicy.init(rawValue: action) ?? WKNavigationActionPolicy.cancel
|
|
}
|
|
return WKNavigationActionPolicy.cancel
|
|
}
|
|
}
|
|
|
|
deinit {
|
|
self.defaultBehaviour(nil)
|
|
}
|
|
}
|
|
|
|
public func shouldOverrideUrlLoading(navigationAction: WKNavigationAction, callback: ShouldOverrideUrlLoadingCallback) {
|
|
if channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
channel?.invokeMethod("shouldOverrideUrlLoading", arguments: navigationAction.toMap(), callback: callback)
|
|
}
|
|
|
|
public func onLoadStart(url: String?) {
|
|
let arguments: [String: Any?] = ["url": url]
|
|
channel?.invokeMethod("onLoadStart", arguments: arguments)
|
|
}
|
|
|
|
public func onLoadStop(url: String?) {
|
|
let arguments: [String: Any?] = ["url": url]
|
|
channel?.invokeMethod("onLoadStop", arguments: arguments)
|
|
}
|
|
|
|
public func onUpdateVisitedHistory(url: String?, isReload: Bool?) {
|
|
let arguments: [String: Any?] = [
|
|
"url": url,
|
|
"isReload": nil
|
|
]
|
|
channel?.invokeMethod("onUpdateVisitedHistory", arguments: arguments)
|
|
}
|
|
|
|
public func onReceivedError(request: WebResourceRequest, error: WebResourceError) {
|
|
let arguments: [String: Any?] = [
|
|
"request": request.toMap(),
|
|
"error": error.toMap()
|
|
]
|
|
channel?.invokeMethod("onReceivedError", arguments: arguments)
|
|
}
|
|
|
|
public func onReceivedHttpError(request: WebResourceRequest, errorResponse: WebResourceResponse) {
|
|
let arguments: [String: Any?] = [
|
|
"request": request.toMap(),
|
|
"errorResponse": errorResponse.toMap()
|
|
]
|
|
channel?.invokeMethod("onReceivedHttpError", arguments: arguments)
|
|
}
|
|
|
|
public class ReceivedHttpAuthRequestCallback: BaseCallbackResult<HttpAuthResponse> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
return HttpAuthResponse.fromMap(map: obj as? [String:Any?])
|
|
}
|
|
}
|
|
|
|
deinit {
|
|
self.defaultBehaviour(nil)
|
|
}
|
|
}
|
|
|
|
public func onReceivedHttpAuthRequest(challenge: HttpAuthenticationChallenge, callback: ReceivedHttpAuthRequestCallback) {
|
|
if channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
// workaround for ProtectionSpace.toMap() SSL Certificate
|
|
// https://github.com/pichillilorenzo/flutter_inappwebview/issues/1678
|
|
DispatchQueue.global(qos: .background).async {
|
|
let arguments = challenge.toMap()
|
|
DispatchQueue.main.async { [weak self] in
|
|
if self?.channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
self?.channel?.invokeMethod("onReceivedHttpAuthRequest", arguments: arguments, callback: callback)
|
|
}
|
|
}
|
|
}
|
|
|
|
public class ReceivedServerTrustAuthRequestCallback: BaseCallbackResult<ServerTrustAuthResponse> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
return ServerTrustAuthResponse.fromMap(map: obj as? [String:Any?])
|
|
}
|
|
}
|
|
|
|
deinit {
|
|
self.defaultBehaviour(nil)
|
|
}
|
|
}
|
|
|
|
public func onReceivedServerTrustAuthRequest(challenge: ServerTrustChallenge, callback: ReceivedServerTrustAuthRequestCallback) {
|
|
if channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
// workaround for ProtectionSpace.toMap() SSL Certificate
|
|
// https://github.com/pichillilorenzo/flutter_inappwebview/issues/1678
|
|
DispatchQueue.global(qos: .background).async {
|
|
let arguments = challenge.toMap()
|
|
DispatchQueue.main.async { [weak self] in
|
|
if self?.channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
self?.channel?.invokeMethod("onReceivedServerTrustAuthRequest", arguments: arguments, callback: callback)
|
|
}
|
|
}
|
|
}
|
|
|
|
public class ReceivedClientCertRequestCallback: BaseCallbackResult<ClientCertResponse> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
return ClientCertResponse.fromMap(map: obj as? [String:Any?])
|
|
}
|
|
}
|
|
|
|
deinit {
|
|
self.defaultBehaviour(nil)
|
|
}
|
|
}
|
|
|
|
public func onReceivedClientCertRequest(challenge: ClientCertChallenge, callback: ReceivedClientCertRequestCallback) {
|
|
if channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
// workaround for ProtectionSpace.toMap() SSL Certificate
|
|
// https://github.com/pichillilorenzo/flutter_inappwebview/issues/1678
|
|
DispatchQueue.global(qos: .background).async {
|
|
let arguments = challenge.toMap()
|
|
DispatchQueue.main.async { [weak self] in
|
|
if self?.channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
self?.channel?.invokeMethod("onReceivedClientCertRequest", arguments: arguments, callback: callback)
|
|
}
|
|
}
|
|
}
|
|
|
|
public func onZoomScaleChanged(newScale: Float, oldScale: Float) {
|
|
let arguments: [String: Any?] = [
|
|
"newScale": newScale,
|
|
"oldScale": oldScale
|
|
]
|
|
channel?.invokeMethod("onZoomScaleChanged", arguments: arguments)
|
|
}
|
|
|
|
public func onPageCommitVisible(url: String?) {
|
|
let arguments: [String: Any?] = [
|
|
"url": url
|
|
]
|
|
channel?.invokeMethod("onPageCommitVisible", arguments: arguments)
|
|
}
|
|
|
|
public class LoadResourceWithCustomSchemeCallback: BaseCallbackResult<CustomSchemeResponse> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
return CustomSchemeResponse.fromMap(map: obj as? [String:Any?])
|
|
}
|
|
}
|
|
}
|
|
|
|
public func onLoadResourceWithCustomScheme(request: WebResourceRequest, callback: LoadResourceWithCustomSchemeCallback) {
|
|
if channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
let arguments: [String: Any?] = ["request": request.toMap()]
|
|
channel?.invokeMethod("onLoadResourceWithCustomScheme", arguments: arguments, callback: callback)
|
|
}
|
|
|
|
public class CallJsHandlerCallback: BaseCallbackResult<Any> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
return obj
|
|
}
|
|
}
|
|
}
|
|
|
|
public func onCallJsHandler(handlerName: String, args: String, callback: CallJsHandlerCallback) {
|
|
if channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
let arguments: [String: Any?] = [
|
|
"handlerName": handlerName,
|
|
"args": args
|
|
]
|
|
channel?.invokeMethod("onCallJsHandler", arguments: arguments, callback: callback)
|
|
}
|
|
|
|
public class NavigationResponseCallback: BaseCallbackResult<WKNavigationResponsePolicy> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
if let action = obj as? Int {
|
|
return WKNavigationResponsePolicy.init(rawValue: action) ?? WKNavigationResponsePolicy.cancel
|
|
}
|
|
return WKNavigationResponsePolicy.cancel
|
|
}
|
|
}
|
|
|
|
deinit {
|
|
self.defaultBehaviour(nil)
|
|
}
|
|
}
|
|
|
|
public func onNavigationResponse(navigationResponse: WKNavigationResponse, callback: NavigationResponseCallback) {
|
|
if channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
channel?.invokeMethod("onNavigationResponse", arguments: navigationResponse.toMap(), callback: callback)
|
|
}
|
|
|
|
public class ShouldAllowDeprecatedTLSCallback: BaseCallbackResult<Bool> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
if let action = obj as? Int {
|
|
return action == 1
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
|
|
deinit {
|
|
self.defaultBehaviour(nil)
|
|
}
|
|
}
|
|
|
|
public func shouldAllowDeprecatedTLS(challenge: URLAuthenticationChallenge, callback: ShouldAllowDeprecatedTLSCallback) {
|
|
if channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
// workaround for ProtectionSpace.toMap() SSL Certificate
|
|
// https://github.com/pichillilorenzo/flutter_inappwebview/issues/1678
|
|
DispatchQueue.global(qos: .background).async {
|
|
let arguments = challenge.toMap()
|
|
DispatchQueue.main.async { [weak self] in
|
|
if self?.channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
self?.channel?.invokeMethod("shouldAllowDeprecatedTLS", arguments: arguments, callback: callback)
|
|
}
|
|
}
|
|
}
|
|
|
|
public func onWebContentProcessDidTerminate() {
|
|
let arguments: [String: Any?] = [:]
|
|
channel?.invokeMethod("onWebContentProcessDidTerminate", arguments: arguments)
|
|
}
|
|
|
|
public func onDidReceiveServerRedirectForProvisionalNavigation() {
|
|
let arguments: [String: Any?] = [:]
|
|
channel?.invokeMethod("onDidReceiveServerRedirectForProvisionalNavigation", arguments: arguments)
|
|
}
|
|
|
|
@available(macOS 12.0, *)
|
|
public func onCameraCaptureStateChanged(oldState: WKMediaCaptureState?, newState: WKMediaCaptureState?) {
|
|
let arguments = [
|
|
"oldState": oldState?.rawValue,
|
|
"newState": newState?.rawValue
|
|
]
|
|
channel?.invokeMethod("onCameraCaptureStateChanged", arguments: arguments)
|
|
}
|
|
|
|
@available(macOS 12.0, *)
|
|
public func onMicrophoneCaptureStateChanged(oldState: WKMediaCaptureState?, newState: WKMediaCaptureState?) {
|
|
let arguments = [
|
|
"oldState": oldState?.rawValue,
|
|
"newState": newState?.rawValue
|
|
]
|
|
channel?.invokeMethod("onMicrophoneCaptureStateChanged", arguments: arguments)
|
|
}
|
|
|
|
public class PrintRequestCallback: BaseCallbackResult<Bool> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
return obj is Bool && obj as! Bool
|
|
}
|
|
}
|
|
}
|
|
|
|
public func onPrintRequest(url: URL?, printJobId: String?, callback: PrintRequestCallback) {
|
|
if channel == nil {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
let arguments = [
|
|
"url": url?.absoluteString,
|
|
"printJobId": printJobId,
|
|
]
|
|
channel?.invokeMethod("onPrintRequest", arguments: arguments, callback: callback)
|
|
}
|
|
|
|
public override func dispose() {
|
|
super.dispose()
|
|
webView = nil
|
|
}
|
|
|
|
deinit {
|
|
debugPrint("WebViewChannelDelegate - dealloc")
|
|
dispose()
|
|
}
|
|
}
|