WKUserScript JS注入

使用 WKUserScript向webView注入js

在WebKit框架中,我们还可以预先添加JS方法,供其他人员调用。WKUserScript就是帮助我们完成JS注入的类,它能帮助我们在页面填充前或js填充完成后调用。核心方法。

注入js , oc代码

- (WKWebView *)webView {
    if (_webView == nil) {
        // js配置
        WKUserContentController *userContentController = [[WKUserContentController alloc] init];
        // js注入,使webview支持 TXWebKitJavascriptBridge_JS 的js 
        WKUserScript *userScript = [[WKUserScript alloc] initWithSource:TXWebKitJavascriptBridge_JS injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];// forMainFrameOnly:NO(全局窗口),yes(只限主窗口)
        [userContentController addUserScript:userScript];
        // WKWebView的配置
        WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
        configuration.userContentController = userContentController;
    // register message handler. 添加 js和原生交互
    [_webView.configuration.userContentController addScriptMessageHandler:self
                                                                     name:TXWVAPI];
    [_webView.configuration.userContentController addScriptMessageHandler:self
                                                                     name:TXWVCALLBACK];
        // 显示WKWebView
        _webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
        [self.view addSubview:_webView];
    }
    return _webView;
}

被注入的js代码 (示例)

//
//  TXWebKitJavascriptBridge_JS.m
//  FloryDay
//
//  Created by Demi on 8/4/16.
//  Copyright © 2016 FloryDay. All rights reserved.
//

#import "TXWebKitJavascriptBridge_JS.h"

NSString *TXWebKitJavascriptBridge_JS()
{
#define __TXWebKitJavascriptBridge_JS_func(x) #x
    
    static NSString *js = @__TXWebKitJavascriptBridge_JS_func(
;(function(){
        if (window.TXWebKitJavascriptBridge) return;
        
        window.TXWebKitJavascriptBridge = {
            _responseHandler        : _response,
            callHandler             : _call,
            registerHandler          : _registerHandler,
            _objc_dispatch_message  : _objc_dispatch_message,
            _registeredHandlers     : _getRegisteredHandler,
            callApp                 : _call
        };
        
        var responseCallbacks = {};
        var uniqueId = 1;
        var registeredHandlers = {}; // js registered handlers
        
        // JS call
        function _call(name, data, respCallback)
        {
            if (arguments.length == 2 && typeof data == 'function')
            {
                respCallback = data;
                data = null;
            }
            _doSend(name, data, respCallback);
        }
        
        // send message to iOS
        function _doSend(name, data, respCallback)
        {
            var message = {data: data, name: name};
            if (respCallback)
            {
                var callbackId = 'cb_'+(uniqueId++)+'_'+new Date().getTime();
                responseCallbacks[callbackId] = respCallback;
                message['cid'] = callbackId;
            }
            window.webkit.messageHandlers.TXWVAPI.postMessage(message);
        }
        
        // iOS response with JS call.
        function _response(callbackId, json)
        {
            var func = responseCallbacks[callbackId];
            if (func)
            {
//                delete responseCallbacks[callbackId];
                if (json)
                {
                    var message = JSON.parse(json);
                    func(message.data);
                }
                else
                {
                    func(null);
                }
                return 'processing';
            }
            else
            {
                return "cann't found callback " + callbackId;
            }
        }
        
        // JS register handler
        function _registerHandler(name, func)
        {
            registeredHandlers[name] = func;
        }
        
        function _getRegisteredHandler()
        {
            return registeredHandlers;
        }
        
        // iOS call
        function _objc_dispatch_message(name, data, cid)
        {
            console.log('registeredHandlers: ' + registeredHandlers);
            var handler = registeredHandlers[name];
            if (handler)
            {
                if (cid)
                {
                    handler(JSON.parse(data), function (resp){
                        window.webkit.messageHandlers.TXWVCALLBACK.postMessage({cid: cid, data: resp});
                    });
                }
                else
                {
                    handler(JSON.parse(data));
                }
                return 'processing';
            }
            else
            {
                console.log("WEBKIT WARRNING: javascript no handler.", name, data);
                if (cid)
                {
                    window.webkit.messageHandlers.TXWVCALLBACK.postMessage({cid: cid});
                }
                return 'no such handler for ' + name;
            }
        }
    })()
                                                              
); // end string
    
#undef __TXWebKitJavascriptBridge_JS_func
    
    return js;
}

实现协议方法 (oc代码)

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
    if ([message.name isEqualToString:TXWVAPI]) {
    } else if ([message.name isEqualToString:TXWVCALLBACK]) {
 }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现 JSBridge 的关键是在原生的 WKWebView 中添加 JavaScript,使之能够被调用并处理传递的数据。以下是一个简单的 Swift 版本的实现: 1. 在原生代码中添加 JavaScript ```swift // WKWebView 初始化 let webView = WKWebView(frame: .zero, configuration: WKWebViewConfiguration()) // 注入 JavaScript 脚本 let jsScript = "window.webkit.messageHandlers.jsBridge.postMessage" let userScript = WKUserScript(source: jsScript, injectionTime: .atDocumentEnd, forMainFrameOnly: false) webView.configuration.userContentController.addUserScript(userScript) // 添加消息处理器 webView.configuration.userContentController.add(self, name: "jsBridge") ``` 2. 实现 WKScriptMessageHandler 协议 使用 WKScriptMessageHandler 协议来接收从 JavaScript 中传递的消息。在 Swift 中,需要使用 `@objc` 来声明方法。 ```swift extension ViewController: WKScriptMessageHandler { func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { if message.name == "jsBridge" { // 处理传递的数据 let data = message.body as? [String: Any] // ... } } } ``` 3. 在 JavaScript 中实现调用 在 JavaScript 中使用 `window.webkit.messageHandlers.jsBridge.postMessage(data)` 来将数据传递给原生代码。以下是一个示例: ```javascript // 发送数据给原生代码 window.webkit.messageHandlers.jsBridge.postMessage({ action: "showAlert", data: { message: "Hello from JavaScript!" } }); ``` 通过以上步骤,就可以在 Swift 中实现一个简单的 JSBridge。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值