// // WebViewMethodHandler.swift // flutter_inappwebview // // Created by Lorenzo Pichilli on 01/02/21. // import Foundation import WebKit class InAppWebViewMethodHandler: FlutterMethodCallDelegate { var webView: InAppWebView? init(webView: InAppWebView) { super.init() 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 url = arguments!["url"] as! String let headers = arguments!["headers"] as! [String: String] webView?.loadUrl(url: URL(string: url)!, headers: headers) result(true) break case "postUrl": if webView != nil { let url = arguments!["url"] as! String let postData = arguments!["postData"] as! FlutterStandardTypedData webView!.postUrl(url: URL(string: url)!, postData: postData.data, completionHandler: { () -> Void in result(true) }) } else { result(false) } break case "loadData": let data = arguments!["data"] as! String let mimeType = arguments!["mimeType"] as! String let encoding = arguments!["encoding"] as! String let baseUrl = arguments!["baseUrl"] as! String webView?.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl) result(true) break case "loadFile": let url = arguments!["url"] as! String let headers = arguments!["headers"] as! [String: String] do { try webView?.loadFile(url: url, headers: headers) } catch let error as NSError { result(FlutterError(code: "InAppWebViewMethodHandler", message: error.domain, details: nil)) return } result(true) break case "evaluateJavascript": if webView != nil { let source = arguments!["source"] as! String let contentWorldName = arguments!["contentWorld"] as? String webView!.evaluateJavascript(source: source, contentWorldName: contentWorldName, result: result) } 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 webView != nil, #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 "setOptions": if let iabController = webView?.IABController { let inAppBrowserOptions = InAppBrowserOptions() let inAppBrowserOptionsMap = arguments!["options"] as! [String: Any] let _ = inAppBrowserOptions.parse(options: inAppBrowserOptionsMap) iabController.setOptions(newOptions: inAppBrowserOptions, newOptionsMap: inAppBrowserOptionsMap) } else { let inAppWebViewOptions = InAppWebViewOptions() let inAppWebViewOptionsMap = arguments!["options"] as! [String: Any] let _ = inAppWebViewOptions.parse(options: inAppWebViewOptionsMap) webView?.setOptions(newOptions: inAppWebViewOptions, newOptionsMap: inAppWebViewOptionsMap) } result(true) break case "getOptions": if let iabController = webView?.IABController { result(iabController.getOptions()) } else { result(webView?.getOptions()) } break case "close": if let iabController = webView?.IABController { iabController.close() result(true) } else { result(FlutterMethodNotImplemented) } break case "show": if let iabController = webView?.IABController { iabController.show() result(true) } else { result(FlutterMethodNotImplemented) } break case "hide": if let iabController = webView?.IABController { iabController.hide() result(true) } else { result(FlutterMethodNotImplemented) } break case "getCopyBackForwardList": result(webView?.getCopyBackForwardList()) break case "findAllAsync": if webView != nil { let find = arguments!["find"] as! String webView!.findAllAsync(find: find, completionHandler: {(value, error) in if error != nil { result(FlutterError(code: "InAppWebViewMethodHandler", message: error?.localizedDescription, details: nil)) return } result(true) }) } else { result(false) } break case "findNext": if webView != nil { let forward = arguments!["forward"] as! Bool webView!.findNext(forward: forward, completionHandler: {(value, error) in if error != nil { result(FlutterError(code: "InAppWebViewMethodHandler", message: error?.localizedDescription, details: nil)) return } result(true) }) } else { result(false) } break case "clearMatches": if webView != nil { webView!.clearMatches(completionHandler: {(value, error) in if error != nil { result(FlutterError(code: "InAppWebViewMethodHandler", 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 webView != nil { webView!.printCurrentPage(printCompletionHandler: {(completed, error) in if !completed, let err = error { print(err.localizedDescription) result(false) return } result(true) }) } else { result(false) } break case "getContentHeight": result(webView?.getContentHeight()) break case "zoomBy": let zoomFactor = arguments!["zoomFactor"] as! Float let animated = arguments!["iosAnimated"] as! Bool webView?.zoomBy(zoomFactor: zoomFactor, animated: animated) result(true) break case "reloadFromOrigin": webView?.reloadFromOrigin() result(true) break case "getScale": result(webView?.getScale()) break case "hasOnlySecureContent": result(webView?.hasOnlySecureContent) break case "getSelectedText": if webView != nil { webView!.getSelectedText { (value, error) in if let err = error { print(err.localizedDescription) result("") return } result(value) } } else { result(nil) } break case "getHitTestResult": if webView != nil { webView!.getHitTestResult { (value, error) in if let err = error { print(err.localizedDescription) result(nil) return } result(value) } } else { result(nil) } break case "clearFocus": webView?.clearFocus() result(true) break case "setContextMenu": if webView != nil { let contextMenu = arguments!["contextMenu"] as? [String: Any] webView!.contextMenu = contextMenu result(true) } else { result(false) } break case "requestFocusNodeHref": if webView != nil { webView!.requestFocusNodeHref { (value, error) in if let err = error { print(err.localizedDescription) result(nil) return } result(value) } } else { result(nil) } break case "requestImageRef": if webView != nil { webView!.requestImageRef { (value, error) in if let err = error { print(err.localizedDescription) result(nil) return } result(value) } } else { result(nil) } break case "getScrollX": if webView != nil { result(Int(webView!.scrollView.contentOffset.x)) } else { result(nil) } break case "getScrollY": if webView != nil { result(Int(webView!.scrollView.contentOffset.y)) } else { result(nil) } break case "getCertificate": result(webView?.getCertificateMap()) break case "addUserScript": let userScript = arguments!["userScript"] as! [String: Any] let wkUserScript = WKUserScript(source: userScript["source"] as! String, injectionTime: WKUserScriptInjectionTime.init(rawValue: userScript["injectionTime"] as! Int) ?? .atDocumentStart, forMainFrameOnly: userScript["iosForMainFrameOnly"] as! Bool) webView?.addUserScript(wkUserScript: wkUserScript) result(true) break case "removeUserScript": let index = arguments!["index"] as! Int webView?.removeUserScript(at: index) result(true) break case "removeAllUserScripts": webView?.removeAllUserScripts() result(true) break case "callAsyncJavaScript": if webView != nil, #available(iOS 10.3, *) { let functionBody = arguments!["functionBody"] as! String let functionArguments = arguments!["arguments"] as! [String:Any] let contentWorldName = arguments!["contentWorld"] as? String webView!.callAsyncJavaScript(functionBody: functionBody, arguments: functionArguments, contentWorldName: contentWorldName, result: result) } else { result(nil) } break case "createPdf": if webView != nil, #available(iOS 14.0, *) { let configuration = arguments!["iosWKPdfConfiguration"] as? [String: Any?] webView!.createPdf(configuration: configuration, completionHandler: { (pdf) -> Void in result(pdf) }) } else { result(nil) } break case "createWebArchiveData": if webView != nil, #available(iOS 14.0, *) { webView!.createWebArchiveData(dataCompletionHandler: { (webArchiveData) -> Void in result(webArchiveData) }) } else { result(nil) } break case "saveWebArchive": if webView != nil, #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 default: result(FlutterMethodNotImplemented) break } } deinit { print("InAppWebViewMethodHandler - dealloc") webView = nil } }