native和WebView交互主要是三种:
1.拦截webView发的出请求
2.native向网页注入脚本
3.native直接调用JS
拦截webView发的出请求
拦截请求就不说了。
native向网页注入脚本
2014WWDC-native和web交互的两种方式从WWDC课件上可以看到,在WKWebView中,我们有
User Script
和Script Messages
两种方对网页内容进行控制。使用这两种方式进行操作的话,都会使用到WKUserContentController这个类。
User Script
User Script的意思是被网页接受的用户脚本。也就是你写到网页脚本是有效的。
它可以用来:
- 更新document
- 监听js事件
- 加载资源
- 与你的程序进行沟通
在WKWebView提供的方法中,你可以设置用户脚本执行的时机是在Html中document开始时候还是结束的时候。 也可以设置用户脚本运行的有效位置是在所有的frame中还是只在主frame中。具体设置方法和枚举如下:
- (instancetype)initWithSource:(NSString *)source injectionTime:(WKUserScriptInjectionTime)injectionTime forMainFrameOnly:(BOOL)forMainFrameOnly;
举例:
比如我在webView中弹出一个提示框,内容是document.cookie中的Cookies,代码如下:
WKUserScript *alertCookieScript = [[WKUserScript alloc] initWithSource:@"alert(document.cookie);" injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:NO];
[contentController addUserScript:alertCookieScript];
webConfiguration.userContentController = contentController;
Script Messages
当我们向网页注入用户脚本,除了单向的让webView做一些东西,还会希望反向获得用户脚本执行的结果活着HTML中元素的值,这个时候就需要用到Script Messages了。WebKit提供了一个WKScriptMessageHandler,通过注册监听的方式接收回调。
通过WKScriptMessageHandler,我们可以:
- 网页可以发送任意的message
- 网页和应用交互
- 处理无效的请求
举例:
获取储存在document.cookie中的Cookies。分为三步。
首先,先想网页中注册用户脚本,作用是当document.cookie中有Cookies的时候,就主动发送消息,这里我们用到User Script:
WKUserScript *cookieScript = [[WKUserScript alloc] initWithSource:@"window.webkit.messageHandlers.currentCookies.postMessage(document.cookie);"" injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:NO];
[contentController addUserScript:cookieScript];
webConfiguration.userContentController = contentController;
然后,注册WKScriptMessageHandler:
// 注册 [userContentController addScriptMessageHandler:handler name:@“currentCookies"];
// 回调
- (void)userContentController:(WKUserContentController
*)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
if ([message.name isEqualToString:@"currentCookies"]) {
NSString *cookiesStr = message.body;
NSLog(@"当前的cookie为: %@", cookiesStr);
}
}
最后,移除注册:
[userContentController removeScriptMessageHandlerForName:@“currentCookies"];
native直接调用JS
UIWebView中也有对应的方法,只不过UIWebView中是同步的,而在WKWebView是异步执行的,这一点需要特别注意。 具体方法如下:
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;
其中:
javaScriptString 是要执行的JS代码
completionHandler 是前一个JS代码的返回结果,注意block中第一个参数是id,具体值是根据你写得JS变化的。
举例:
获取名字叫meta
的标签的长度
- (void)ocCallJavaScript:(void(^)(void))complete
{
[self.webView evaluateJavaScript:@"document.getElementsByTagName('meta').length"
completionHandler:^(NSString *count, NSError * _Nullable error)
{
!complete ? complete();
}];
}
参考
交流
希望能和大家交流技术
Blog:http://www.lilongcnc.cc
网友评论