From 36a299d8c960e9b838b63b995121b55227b76bd7 Mon Sep 17 00:00:00 2001 From: Lorenzo Pichilli Date: Mon, 11 Dec 2023 16:12:08 +0100 Subject: [PATCH] fix #1912 --- flutter_inappwebview/CHANGELOG.md | 12 +++ flutter_inappwebview_ios/CHANGELOG.md | 1 + .../Classes/InAppWebView/InAppWebView.swift | 58 +++++++-------- flutter_inappwebview_macos/CHANGELOG.md | 1 + .../Classes/InAppWebView/InAppWebView.swift | 74 +++++++++---------- 5 files changed, 73 insertions(+), 73 deletions(-) diff --git a/flutter_inappwebview/CHANGELOG.md b/flutter_inappwebview/CHANGELOG.md index f5853796..0391dbad 100755 --- a/flutter_inappwebview/CHANGELOG.md +++ b/flutter_inappwebview/CHANGELOG.md @@ -1,7 +1,19 @@ ## 6.0.0-beta.32 - Updated minimum platform interface and implementation versions +- Updated `useShouldInterceptAjaxRequest` automatic infer logic - Added `InAppWebViewSettings.interceptOnlyAsyncAjaxRequests` [#1905](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1905) +- Fixed "iOS crash at public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)" [#1912](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1912) +- Fixed "iOS Fatal Crash" [#1894](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1894) +- Fixed "getFavicons: _TypeError: type '_Map' is not a subtype of type 'Iterable'" [#1897](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1897) +- Fixed error in InterceptAjaxRequestJS 'Failed to set responseType property' +- Fixed shouldInterceptAjaxRequest javascript code when overriding XMLHttpRequest.open method parameters +- Fixed "onClosed not considering back navigation or up button / close button in ChromeSafariBrowser when using noHistory: true" [#1882](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1882) +- Merged "Fixed error in InterceptAjaxRequestJS 'Failed to set responseType property'" [#1904](https://github.com/pichillilorenzo/flutter_inappwebview/pull/1904) (thanks to [EArminjon](https://github.com/EArminjon)) + +### BREAKING CHANGE + +- Due to Flutter platform channels async nature, using `useShouldInterceptAjaxRequest: true` would break sync ajax requests, so that the `XMLHttpRequest.send()` will not wait for the response. To fix this issue, the default value of `InAppWebViewSettings.interceptOnlyAsyncAjaxRequests` is `true`. To intercept also sync ajax requests, this value should be `false`. ## 6.0.0-beta.31 diff --git a/flutter_inappwebview_ios/CHANGELOG.md b/flutter_inappwebview_ios/CHANGELOG.md index 6a5fa537..014bb3e5 100644 --- a/flutter_inappwebview_ios/CHANGELOG.md +++ b/flutter_inappwebview_ios/CHANGELOG.md @@ -2,6 +2,7 @@ - Implemented `InAppWebViewSettings.interceptOnlyAsyncAjaxRequests` - Updated `useShouldInterceptAjaxRequest` automatic infer logic +- Fixed "iOS crash at public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)" [#1912](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1912) ## 1.0.8 diff --git a/flutter_inappwebview_ios/ios/Classes/InAppWebView/InAppWebView.swift b/flutter_inappwebview_ios/ios/Classes/InAppWebView/InAppWebView.swift index a0b3d201..f2e7e1b5 100755 --- a/flutter_inappwebview_ios/ios/Classes/InAppWebView/InAppWebView.swift +++ b/flutter_inappwebview_ios/ios/Classes/InAppWebView/InAppWebView.swift @@ -2780,7 +2780,11 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, // } public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { - if message.name.starts(with: "console") { + guard let body = message.body as? [String: Any?] else { + return + } + + if ["consoleLog", "consoleDebug", "consoleError", "consoleInfo", "consoleWarn"].contains(message.name) { var messageLevel = 1 switch (message.name) { case "consoleLog": @@ -2804,8 +2808,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, messageLevel = 1 break; } - let body = message.body as! [String: Any?] - let consoleMessage = body["message"] as! String + let consoleMessage = body["message"] as? String ?? "" let _windowId = body["_windowId"] as? Int64 var webView = self @@ -2813,10 +2816,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, webView = webViewTransport.webView } webView.channelDelegate?.onConsoleMessage(message: consoleMessage, messageLevel: messageLevel) - } else if message.name == "callHandler" { - let body = message.body as! [String: Any?] - let handlerName = body["handlerName"] as! String - + } else if message.name == "callHandler", let handlerName = body["handlerName"] as? String { if handlerName == "onPrintRequest" { let settings = PrintJobSettings() settings.handledByClient = true @@ -2839,8 +2839,8 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, return } - let _callHandlerID = body["_callHandlerID"] as! Int64 - let args = body["args"] as! String + let _callHandlerID = body["_callHandlerID"] as? Int64 ?? 0 + let args = body["args"] as? String ?? "" let _windowId = body["_windowId"] as? Int64 var webView = self @@ -2877,12 +2877,11 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) { if let channelDelegate = webView.channelDelegate { channelDelegate.onCallJsHandler(handlerName: handlerName, args: args, callback: callback) } - } else if message.name == "onFindResultReceived" { - let body = message.body as! [String: Any?] - let findResult = body["findResult"] as! [String: Any] - let activeMatchOrdinal = findResult["activeMatchOrdinal"] as! Int - let numberOfMatches = findResult["numberOfMatches"] as! Int - let isDoneCounting = findResult["isDoneCounting"] as! Bool + } else if message.name == "onFindResultReceived", + let findResult = body["findResult"] as? [String: Any], + let activeMatchOrdinal = findResult["activeMatchOrdinal"] as? Int, + let numberOfMatches = findResult["numberOfMatches"] as? Int, + let isDoneCounting = findResult["isDoneCounting"] as? Bool { let _windowId = body["_windowId"] as? Int64 var webView = self @@ -2891,20 +2890,17 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) { } webView.findInteractionController?.channelDelegate?.onFindResultReceived(activeMatchOrdinal: activeMatchOrdinal, numberOfMatches: numberOfMatches, isDoneCounting: isDoneCounting) webView.channelDelegate?.onFindResultReceived(activeMatchOrdinal: activeMatchOrdinal, numberOfMatches: numberOfMatches, isDoneCounting: isDoneCounting) - } else if message.name == "onCallAsyncJavaScriptResultBelowIOS14Received" { - let body = message.body as! [String: Any?] - let resultUuid = body["resultUuid"] as! String - if let result = callAsyncJavaScriptBelowIOS14Results[resultUuid] { - result([ - "value": body["value"], - "error": body["error"] - ]) - callAsyncJavaScriptBelowIOS14Results.removeValue(forKey: resultUuid) - } - } else if message.name == "onWebMessagePortMessageReceived" { - let body = message.body as! [String: Any?] - let webMessageChannelId = body["webMessageChannelId"] as! String - let index = body["index"] as! Int64 + } else if message.name == "onCallAsyncJavaScriptResultBelowIOS14Received", + let resultUuid = body["resultUuid"] as? String, + let result = callAsyncJavaScriptBelowIOS14Results[resultUuid] { + result([ + "value": body["value"], + "error": body["error"] + ]) + callAsyncJavaScriptBelowIOS14Results.removeValue(forKey: resultUuid) + } else if message.name == "onWebMessagePortMessageReceived", + let webMessageChannelId = body["webMessageChannelId"] as? String, + let index = body["index"] as? Int64 { var webMessage: WebMessage? = nil if let webMessageMap = body["message"] as? [String : Any?] { webMessage = WebMessage.fromMap(map: webMessageMap) @@ -2913,9 +2909,7 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) { if let webMessageChannel = webMessageChannels[webMessageChannelId] { webMessageChannel.channelDelegate?.onMessage(index: index, message: webMessage) } - } else if message.name == "onWebMessageListenerPostMessageReceived" { - let body = message.body as! [String: Any?] - let jsObjectName = body["jsObjectName"] as! String + } else if message.name == "onWebMessageListenerPostMessageReceived", let jsObjectName = body["jsObjectName"] as? String { var webMessage: WebMessage? = nil if let webMessageMap = body["message"] as? [String : Any?] { webMessage = WebMessage.fromMap(map: webMessageMap) diff --git a/flutter_inappwebview_macos/CHANGELOG.md b/flutter_inappwebview_macos/CHANGELOG.md index 7b05a820..dd346528 100644 --- a/flutter_inappwebview_macos/CHANGELOG.md +++ b/flutter_inappwebview_macos/CHANGELOG.md @@ -2,6 +2,7 @@ - Implemented `InAppWebViewSettings.interceptOnlyAsyncAjaxRequests` - Updated `useShouldInterceptAjaxRequest` automatic infer logic +- Fixed "iOS crash at public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)" [#1912](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1912) ## 1.0.6 diff --git a/flutter_inappwebview_macos/macos/Classes/InAppWebView/InAppWebView.swift b/flutter_inappwebview_macos/macos/Classes/InAppWebView/InAppWebView.swift index d68c0199..304655da 100755 --- a/flutter_inappwebview_macos/macos/Classes/InAppWebView/InAppWebView.swift +++ b/flutter_inappwebview_macos/macos/Classes/InAppWebView/InAppWebView.swift @@ -44,7 +44,7 @@ public class InAppWebView: WKWebView, WKUIDelegate, var customIMPs: [IMP] = [] - var callAsyncJavaScriptBelowIOS14Results: [String:((Any?) -> Void)] = [:] + var callAsyncJavaScriptBelowMacOS11Results: [String:((Any?) -> Void)] = [:] var currentOpenPanel: NSOpenPanel? @@ -941,7 +941,7 @@ public class InAppWebView: WKWebView, WKUIDelegate, let resultUuid = NSUUID().uuidString if let completionHandler = completionHandler { - callAsyncJavaScriptBelowIOS14Results[resultUuid] = completionHandler + callAsyncJavaScriptBelowMacOS11Results[resultUuid] = completionHandler } var functionArgumentNamesList: [String] = [] @@ -970,7 +970,7 @@ public class InAppWebView: WKWebView, WKUIDelegate, error.localizedDescription self.channelDelegate?.onConsoleMessage(message: String(describing: errorMessage), messageLevel: 3) completionHandler?(nil) - self.callAsyncJavaScriptBelowIOS14Results.removeValue(forKey: resultUuid) + self.callAsyncJavaScriptBelowMacOS11Results.removeValue(forKey: resultUuid) } } } @@ -2083,7 +2083,11 @@ public class InAppWebView: WKWebView, WKUIDelegate, // } public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { - if message.name.starts(with: "console") { + guard let body = message.body as? [String: Any?] else { + return + } + + if ["consoleLog", "consoleDebug", "consoleError", "consoleInfo", "consoleWarn"].contains(message.name) { var messageLevel = 1 switch (message.name) { case "consoleLog": @@ -2107,8 +2111,7 @@ public class InAppWebView: WKWebView, WKUIDelegate, messageLevel = 1 break; } - let body = message.body as! [String: Any?] - let consoleMessage = body["message"] as! String + let consoleMessage = body["message"] as? String ?? "" let _windowId = body["_windowId"] as? Int64 var webView = self @@ -2116,10 +2119,7 @@ public class InAppWebView: WKWebView, WKUIDelegate, webView = webViewTransport.webView } webView.channelDelegate?.onConsoleMessage(message: consoleMessage, messageLevel: messageLevel) - } else if message.name == "callHandler" { - let body = message.body as! [String: Any?] - let handlerName = body["handlerName"] as! String - + } else if message.name == "callHandler", let handlerName = body["handlerName"] as? String { if handlerName == "onPrintRequest" { let settings = PrintJobSettings() settings.handledByClient = true @@ -2142,8 +2142,8 @@ public class InAppWebView: WKWebView, WKUIDelegate, return } - let _callHandlerID = body["_callHandlerID"] as! Int64 - let args = body["args"] as! String + let _callHandlerID = body["_callHandlerID"] as? Int64 ?? 0 + let args = body["args"] as? String ?? "" let _windowId = body["_windowId"] as? Int64 var webView = self @@ -2180,12 +2180,11 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) { if let channelDelegate = webView.channelDelegate { channelDelegate.onCallJsHandler(handlerName: handlerName, args: args, callback: callback) } - } else if message.name == "onFindResultReceived" { - let body = message.body as! [String: Any?] - let findResult = body["findResult"] as! [String: Any] - let activeMatchOrdinal = findResult["activeMatchOrdinal"] as! Int - let numberOfMatches = findResult["numberOfMatches"] as! Int - let isDoneCounting = findResult["isDoneCounting"] as! Bool + } else if message.name == "onFindResultReceived", + let findResult = body["findResult"] as? [String: Any], + let activeMatchOrdinal = findResult["activeMatchOrdinal"] as? Int, + let numberOfMatches = findResult["numberOfMatches"] as? Int, + let isDoneCounting = findResult["isDoneCounting"] as? Bool { let _windowId = body["_windowId"] as? Int64 var webView = self @@ -2194,31 +2193,26 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) { } webView.findInteractionController?.channelDelegate?.onFindResultReceived(activeMatchOrdinal: activeMatchOrdinal, numberOfMatches: numberOfMatches, isDoneCounting: isDoneCounting) webView.channelDelegate?.onFindResultReceived(activeMatchOrdinal: activeMatchOrdinal, numberOfMatches: numberOfMatches, isDoneCounting: isDoneCounting) - } else if message.name == "onScrollChanged" { - let body = message.body as! [String: Any?] - let x = body["x"] as! Int - let y = body["y"] as! Int - + } else if message.name == "onScrollChanged", + let x = body["x"] as? Int, + let y = body["y"] as? Int { let _windowId = body["_windowId"] as? Int64 var webView = self if let wId = _windowId, let webViewTransport = plugin?.inAppWebViewManager?.windowWebViews[wId] { webView = webViewTransport.webView } webView.channelDelegate?.onScrollChanged(x: x, y: y) - } else if message.name == "onCallAsyncJavaScriptResultBelowIOS14Received" { - let body = message.body as! [String: Any?] - let resultUuid = body["resultUuid"] as! String - if let result = callAsyncJavaScriptBelowIOS14Results[resultUuid] { - result([ - "value": body["value"], - "error": body["error"] - ]) - callAsyncJavaScriptBelowIOS14Results.removeValue(forKey: resultUuid) - } - } else if message.name == "onWebMessagePortMessageReceived" { - let body = message.body as! [String: Any?] - let webMessageChannelId = body["webMessageChannelId"] as! String - let index = body["index"] as! Int64 + } else if message.name == "onCallAsyncJavaScriptResultBelowIOS14Received", + let resultUuid = body["resultUuid"] as? String, + let result = callAsyncJavaScriptBelowMacOS11Results[resultUuid] { + result([ + "value": body["value"], + "error": body["error"] + ]) + callAsyncJavaScriptBelowMacOS11Results.removeValue(forKey: resultUuid) + } else if message.name == "onWebMessagePortMessageReceived", + let webMessageChannelId = body["webMessageChannelId"] as? String, + let index = body["index"] as? Int64 { var webMessage: WebMessage? = nil if let webMessageMap = body["message"] as? [String : Any?] { webMessage = WebMessage.fromMap(map: webMessageMap) @@ -2227,9 +2221,7 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) { if let webMessageChannel = webMessageChannels[webMessageChannelId] { webMessageChannel.channelDelegate?.onMessage(index: index, message: webMessage) } - } else if message.name == "onWebMessageListenerPostMessageReceived" { - let body = message.body as! [String: Any?] - let jsObjectName = body["jsObjectName"] as! String + } else if message.name == "onWebMessageListenerPostMessageReceived", let jsObjectName = body["jsObjectName"] as? String { var webMessage: WebMessage? = nil if let webMessageMap = body["message"] as? [String : Any?] { webMessage = WebMessage.fromMap(map: webMessageMap) @@ -2644,7 +2636,7 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) { uiDelegate = nil navigationDelegate = nil isPausedTimersCompletionHandler = nil - callAsyncJavaScriptBelowIOS14Results.removeAll() + callAsyncJavaScriptBelowMacOS11Results.removeAll() plugin = nil }