亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

iOS 14 API WKScriptMessageHandlerWithReply 如何從 iOS

iOS 14 API WKScriptMessageHandlerWithReply 如何從 iOS

寶慕林4294392 2023-11-12 22:14:38
iOS 14 引入了一種新方法來接收 javascript 調用并使用 WKScriptMessageHandlerWithReply 而不是 WKScriptMessageHandler(在 WebKit 視圖內)提供響應。然而文檔基本上不存在。這是如何運作的?
查看完整描述

1 回答

?
侃侃無極

TA貢獻2051條經驗 獲得超10個贊

我對此進行了深入研究,發現它使用 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 代碼加載并注入到網頁中的 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 發起的請求成功或失敗時由應用程序擴展代碼調用的函數。


查看完整回答
反對 回復 2023-11-12
  • 1 回答
  • 0 關注
  • 380 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號