似乎问题的一部分是方法重载,从 Xcode 14.1 开始,有几个方法名为 evaluateJavaScript 作为WKWebView 的一部分。
由于可选参数,它们似乎具有相同的签名,编译器很难理解我们的意思。
方法
open func evaluateJavaScript(_ javaScriptString: String, completionHandler: ((Any?, Error?) -> Void)? = nil)
open func evaluateJavaScript(_ javaScriptString: String) async throws -> Any
@MainActor public func evaluateJavaScript(_ javaScript: String, in frame: WKFrameInfo? = nil, in contentWorld: WKContentWorld, completionHandler: ((Result<Any, Error>) -> Void)? = nil)
@MainActor public func evaluateJavaScript(_ javaScript: String, in frame: WKFrameInfo? = nil, contentWorld: WKContentWorld) async throws -> Any?
在测试了不同的场景之后,似乎在使用这些方法的async/await 版本时,WKWebView 期望 JavaScript 返回一个值(Void 以外的其他值),如果您评估的 JavaScript 没有返回值,您将拥有崩溃。
解决方案
选项1
始终确保 JavaScript 返回一个值。
崩溃:
try? await webView.evaluateJavaScript("console.log('hello world')") // fatal error
不崩溃:
try? await webView.evaluateJavaScript("console.log('hello world'); 0")
选项 2
如果无法显式返回值,请使用带有完成处理程序的签名(即使您将 nil 作为处理程序传递)。
webView.evaluateJavaScript("console.log('hello world')", completionHandler: nil)