gpt4 book ai didi

javascript - iOS 14 API WKScriptMessageHandlerWithReply 如何与 iOS 中的 JavaScript 通信?

转载 作者:行者123 更新时间:2023-12-05 00:44:54 33 4
gpt4 key购买 nike

iOS 14 引入了一种新的方式来接收 javascript 调用并使用 WKScriptMessageHandlerWithReply 而不是 WKScriptMessageHandler(在 WebKit View 中)提供响应。但是文档基本上不存在。这是如何工作的?

最佳答案

我对此进行了深入研究,发现它使用 Javascript Promises 来提供回调机制(并且从应用程序代码返回到 javascript 的响应必须是异步的)。

这里有一些示例代码来说明:

快速代码:

import UIKit
import WebKit
import PureLayout

final class ViewController: UIViewController {

var webView : WKWebView?
let JavaScriptAPIObjectName = "namespaceWithinTheInjectedJSCode"

override func viewDidLoad() {
super.viewDidLoad()

//-------

guard let scriptPath = Bundle.main.path(forResource: "script", ofType: "js"),
let scriptSource = try? String(contentsOfFile: scriptPath) else { return }

let userScript = WKUserScript(source: scriptSource, injectionTime: .atDocumentEnd, forMainFrameOnly: true)

let config = WKWebViewConfiguration()

let userContentController = WKUserContentController()
userContentController.addUserScript(userScript)

// REQUIRES IOS14
if #available(iOS 14, *){
userContentController.addScriptMessageHandler(self, contentWorld: .page, name: JavaScriptAPIObjectName)
}

config.userContentController = userContentController

webView = WKWebView(frame: .zero, configuration: config)

if let webView = webView{
view.addSubview(webView)
webView.autoPinEdgesToSuperviewMargins() // using PureLayout for easy AutoLayout syntax

if let htmlPath = Bundle.main.url(forResource: "page", withExtension: "html"){
webView.loadFileURL( htmlPath, allowingReadAccessTo: htmlPath);
}
}
}

// need to deinit and remove webview stuff
deinit {
if let webView = webView{
let ucc = webView.configuration.userContentController
ucc.removeAllUserScripts()
ucc.removeScriptMessageHandler(forName:JavaScriptAPIObjectName)
}
}
}

extension ViewController: WKScriptMessageHandlerWithReply {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage, replyHandler: @escaping (Any?, String?) -> Void) {
if message.name == JavaScriptAPIObjectName, let messageBody = message.body as? String {
print(messageBody)
replyHandler( 2.2, nil ) // first var is success return val, second is err string if error
}
}
}

这是通过该 Swift 代码加载并注入(inject)网页的 script.js:

function sampleMethodTheHTMLCanCall( inputInfo, successFunc, errorFunc ) {

var promise = window.webkit.messageHandlers.namespaceWithinTheInjectedJSCode.postMessage( inputInfo );

promise.then(
function(result) {
console.log(result); // "Stuff worked!"
successFunc( result )
},
function(err) {
console.log(err); // Error: "It broke"
errorFunc( err )
});
}

这里是可以调用应用程序代码的 page.html 示例 HTML:

<html>
<meta name="viewport" content="width=device-width" />
<script>
function handleInfoFromApp( fromApp ){
document.getElementById("valToWrite").innerHTML = fromApp;
}
function handleError( err ){

}
</script>

<h1 id="valToWrite">Hello</h1>
<button onclick="sampleMethodTheHTMLCanCall( 'inputInfo', handleInfoFromApp, handleError )">Load Info from App</button>

</html>

上面的 HTML 提供了稍后在 javascript 发起的请求成功或失败时由应用扩展代码调用的函数。

关于javascript - iOS 14 API WKScriptMessageHandlerWithReply 如何与 iOS 中的 JavaScript 通信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65270083/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com