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]) {
}
}