1085 lines
41 KiB
Swift
1085 lines
41 KiB
Swift
//
|
|
// WebViewChannelDelegate.swift
|
|
// flutter_inappwebview
|
|
//
|
|
// Created by Lorenzo Pichilli on 06/05/22.
|
|
//
|
|
|
|
import Foundation
|
|
import WebKit
|
|
|
|
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
|
|
|
|
switch call.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(iOS 14.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(iOS 11.0, *) {
|
|
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 "getCopyBackForwardList":
|
|
result(webView?.getCopyBackForwardList())
|
|
break
|
|
case "findAllAsync":
|
|
if let webView = webView {
|
|
let find = arguments!["find"] as! String
|
|
webView.findAllAsync(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 forward = arguments!["forward"] as! Bool
|
|
webView.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 {
|
|
webView.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":
|
|
result(webView?.getContentHeight())
|
|
break
|
|
case "zoomBy":
|
|
let zoomFactor = (arguments!["zoomFactor"] as! NSNumber).floatValue
|
|
let animated = arguments!["animated"] as! Bool
|
|
webView?.zoomBy(zoomFactor: zoomFactor, animated: animated)
|
|
result(true)
|
|
break
|
|
case "reloadFromOrigin":
|
|
webView?.reloadFromOrigin()
|
|
result(true)
|
|
break
|
|
case "getOriginalUrl":
|
|
result(webView?.getOriginalUrl()?.absoluteString)
|
|
break
|
|
case "getZoomScale":
|
|
result(webView?.getZoomScale())
|
|
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 "getHitTestResult":
|
|
if let webView = webView {
|
|
webView.getHitTestResult { (hitTestResult) in
|
|
result(hitTestResult.toMap())
|
|
}
|
|
}
|
|
else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case "clearFocus":
|
|
webView?.clearFocus()
|
|
result(true)
|
|
break
|
|
case "setContextMenu":
|
|
if let webView = webView {
|
|
let contextMenu = arguments!["contextMenu"] as? [String: Any]
|
|
webView.contextMenu = contextMenu
|
|
result(true)
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case "requestFocusNodeHref":
|
|
if let webView = webView {
|
|
webView.requestFocusNodeHref { (value, error) in
|
|
if let err = error {
|
|
print(err.localizedDescription)
|
|
result(nil)
|
|
return
|
|
}
|
|
result(value)
|
|
}
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case "requestImageRef":
|
|
if let webView = webView {
|
|
webView.requestImageRef { (value, error) in
|
|
if let err = error {
|
|
print(err.localizedDescription)
|
|
result(nil)
|
|
return
|
|
}
|
|
result(value)
|
|
}
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case "getScrollX":
|
|
if let webView = webView {
|
|
result(Int(webView.scrollView.contentOffset.x))
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case "getScrollY":
|
|
if let webView = webView {
|
|
result(Int(webView.scrollView.contentOffset.y))
|
|
} 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, #available(iOS 10.3, *) {
|
|
if #available(iOS 14.0, *) {
|
|
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(iOS 14.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(iOS 14.0, *) {
|
|
webView.createWebArchiveData(dataCompletionHandler: { (webArchiveData) -> Void in
|
|
result(webArchiveData)
|
|
})
|
|
}
|
|
else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case "saveWebArchive":
|
|
if let webView = webView, #available(iOS 14.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
|
|
result(webMessageChannel.toMap())
|
|
}
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case "postWebMessage":
|
|
if let webView = webView {
|
|
let message = arguments!["message"] as! [String: Any?]
|
|
let targetOrigin = arguments!["targetOrigin"] as! String
|
|
|
|
var ports: [WebMessagePort] = []
|
|
let portsMap = message["ports"] as? [[String: Any?]]
|
|
if let portsMap = portsMap {
|
|
for portMap in portsMap {
|
|
let webMessageChannelId = portMap["webMessageChannelId"] as! String
|
|
let index = portMap["index"] as! Int
|
|
if let webMessageChannel = webView.webMessageChannels[webMessageChannelId] {
|
|
ports.append(webMessageChannel.ports[index])
|
|
}
|
|
}
|
|
}
|
|
let webMessage = WebMessage(data: message["data"] as? String, ports: ports)
|
|
do {
|
|
try webView.postWebMessage(message: webMessage, 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 webMessageListenerMap = arguments!["webMessageListener"] as! [String: Any?]
|
|
let webMessageListener = WebMessageListener.fromMap(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 {
|
|
result(webView.canScrollVertically())
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case "canScrollHorizontally":
|
|
if let webView = webView {
|
|
result(webView.canScrollHorizontally())
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case "pauseAllMediaPlayback":
|
|
if let webView = webView, #available(iOS 15.0, *) {
|
|
webView.pauseAllMediaPlayback(completionHandler: { () -> Void in
|
|
result(true)
|
|
})
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case "setAllMediaPlaybackSuspended":
|
|
if let webView = webView, #available(iOS 15.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(iOS 14.5, *) {
|
|
// closeAllMediaPresentations with completionHandler v15.0 makes the app crash
|
|
// with error EXC_BAD_ACCESS, so use closeAllMediaPresentations v14.5
|
|
webView.closeAllMediaPresentations()
|
|
result(true)
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
case "requestMediaPlaybackState":
|
|
if let webView = webView, #available(iOS 15.0, *) {
|
|
webView.requestMediaPlaybackState(completionHandler: { (state) -> Void in
|
|
result(state.rawValue)
|
|
})
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case "getMetaThemeColor":
|
|
if let webView = webView, #available(iOS 15.0, *) {
|
|
result(webView.themeColor?.hexString)
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case "isInFullscreen":
|
|
// if let webView = webView, #available(iOS 15.0, *) {
|
|
// result(webView.fullscreenState == .inFullscreen)
|
|
// }
|
|
if let webView = webView {
|
|
result(webView.inFullscreen)
|
|
}
|
|
else {
|
|
result(false)
|
|
}
|
|
break
|
|
case "getCameraCaptureState":
|
|
if let webView = webView, #available(iOS 15.0, *) {
|
|
result(webView.cameraCaptureState.rawValue)
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case "setCameraCaptureState":
|
|
if let webView = webView, #available(iOS 15.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(iOS 15.0, *) {
|
|
result(webView.microphoneCaptureState.rawValue)
|
|
} else {
|
|
result(nil)
|
|
}
|
|
break
|
|
case "setMicrophoneCaptureState":
|
|
if let webView = webView, #available(iOS 15.0, *) {
|
|
let state = WKMediaCaptureState.init(rawValue: arguments!["state"] as! Int) ?? WKMediaCaptureState.none
|
|
webView.setMicrophoneCaptureState(state) {
|
|
result(true)
|
|
}
|
|
} else {
|
|
result(false)
|
|
}
|
|
break
|
|
default:
|
|
result(FlutterMethodNotImplemented)
|
|
break
|
|
}
|
|
}
|
|
|
|
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("onJsConfirm", 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?])
|
|
}
|
|
}
|
|
}
|
|
|
|
public func onPermissionRequest(request: PermissionRequest, callback: PermissionRequestCallback) {
|
|
guard let channel = channel else {
|
|
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 obj = obj as? [String: Any?], let action = obj["action"] as? Int {
|
|
return WKNavigationActionPolicy.init(rawValue: action) ?? WKNavigationActionPolicy.cancel
|
|
}
|
|
return WKNavigationActionPolicy.cancel
|
|
}
|
|
}
|
|
}
|
|
|
|
public func shouldOverrideUrlLoading(navigationAction: WKNavigationAction, callback: ShouldOverrideUrlLoadingCallback) {
|
|
guard let channel = channel else {
|
|
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?])
|
|
}
|
|
}
|
|
}
|
|
|
|
public func onReceivedHttpAuthRequest(challenge: HttpAuthenticationChallenge, callback: ReceivedHttpAuthRequestCallback) {
|
|
guard let channel = channel else {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
channel.invokeMethod("onReceivedHttpAuthRequest", arguments: challenge.toMap(), callback: callback)
|
|
}
|
|
|
|
public class ReceivedServerTrustAuthRequestCallback : BaseCallbackResult<ServerTrustAuthResponse> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
return ServerTrustAuthResponse.fromMap(map: obj as? [String:Any?])
|
|
}
|
|
}
|
|
}
|
|
|
|
public func onReceivedServerTrustAuthRequest(challenge: ServerTrustChallenge, callback: ReceivedServerTrustAuthRequestCallback) {
|
|
guard let channel = channel else {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
channel.invokeMethod("onReceivedServerTrustAuthRequest", arguments: challenge.toMap(), callback: callback);
|
|
}
|
|
|
|
public class ReceivedClientCertRequestCallback : BaseCallbackResult<ClientCertResponse> {
|
|
override init() {
|
|
super.init()
|
|
self.decodeResult = { (obj: Any?) in
|
|
return ClientCertResponse.fromMap(map: obj as? [String:Any?])
|
|
}
|
|
}
|
|
}
|
|
|
|
public func onReceivedClientCertRequest(challenge: ClientCertChallenge, callback: ReceivedClientCertRequestCallback) {
|
|
guard let channel = channel else {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
channel.invokeMethod("onReceivedClientCertRequest", arguments: challenge.toMap(), 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) {
|
|
guard let channel = channel else {
|
|
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) {
|
|
guard let channel = channel else {
|
|
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 obj = obj as? [String: Any?], let action = obj["action"] as? Int {
|
|
return WKNavigationResponsePolicy.init(rawValue: action) ?? WKNavigationResponsePolicy.cancel
|
|
}
|
|
return WKNavigationResponsePolicy.cancel
|
|
}
|
|
}
|
|
}
|
|
|
|
public func onNavigationResponse(navigationResponse: WKNavigationResponse, callback: NavigationResponseCallback) {
|
|
guard let channel = channel else {
|
|
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 obj = obj as? [String: Any?], let action = obj["action"] as? Int {
|
|
return action == 1
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
public func shouldAllowDeprecatedTLS(challenge: URLAuthenticationChallenge, callback: ShouldAllowDeprecatedTLSCallback) {
|
|
guard let channel = channel else {
|
|
callback.defaultBehaviour(nil)
|
|
return
|
|
}
|
|
channel.invokeMethod("shouldAllowDeprecatedTLS", arguments: challenge.toMap(), 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(iOS 15.0, *)
|
|
public func onCameraCaptureStateChanged(oldState: WKMediaCaptureState?, newState: WKMediaCaptureState?) {
|
|
let arguments = [
|
|
"oldState": oldState?.rawValue,
|
|
"newState": newState?.rawValue
|
|
]
|
|
channel?.invokeMethod("onCameraCaptureStateChanged", arguments: arguments)
|
|
}
|
|
|
|
@available(iOS 15.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) {
|
|
guard let channel = channel else {
|
|
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()
|
|
}
|
|
}
|