ios WKWebView 与 JS 交互实战技巧
来源:互联网 发布:linux中tail命令 编辑:程序博客网 时间:2024/05/29 10:09
作者:张文宇 向日葵远程控制软件/花生壳/蒲公英路由器 iOS高级软件工程师
最近公司需要针对向日葵远程控制和花生壳动态域名解析服务客户端 做与HTML5交互的App,优点就是开发周期短,可随时更新内容。所以在这整理了一些 App 与 Web 交互的方法。
一、WKWebView
由于Xcode8发布之后,编译器开始不支持iOS 7了,这样我们的app也改为最低支持iOS 8.0,既然需要与web交互,那自然也就选择使用了 iOS 8.0之后 才推出的新控件 WKWebView
.
相比与 UIWebView
, WKWebView
存在很多优势:
- 支持更多的HTML5的特性
- 高达60fps滚动刷新频率与内置手势
- 与Safari相容的JavaScript引擎
- 在性能、稳定性方面有很大提升占用内存更少
协议方法及功能都更细致 - 可获取加载进度等。
二、WKWebView 用法简介
注:本文主要说明WKWebView
与JS的交互,这里只简单介绍WKWebView
基础用法,其他具体详细用法详见官方文档
需要引入WebKit
#import <WebKit/WebKit.h>
实例化
/*! @abstract Returns a web view initialized with a specified frame and configuration. @param frame The frame for the new web view. @param configuration The configuration for the new web view. @result An initialized web view, or nil if the object could not be initialized. @discussion This is a designated initializer. You can use @link -initWithFrame: @/link to initialize an instance with the default configuration. The initializer copies the specified configuration, so mutating the configuration after invoking the initializer has no effect on the web view. */- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration NS_DESIGNATED_INITIALIZER;
加载HTML页面
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc]init];WKWebView *webView = [[WKWebView alloc]initWithFrame:self.view.bounds configuration:config];NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:@"https://www.baidu.com"]];[webView loadRequest:request];[self.view addSubview:webView];
这里只需load即可 与UIWebView
使用相同,下面简单介绍一下两个常用的代理
三、WKWebView 代理
WKWebView
有两个代理:
/*! @abstract The web view's navigation delegate. */@property (nullable, nonatomic, weak) id <WKNavigationDelegate> navigationDelegate;/*! @abstract The web view's user interface delegate. */@property (nullable, nonatomic, weak) id <WKUIDelegate> UIDelegate;
WKNavigationDelegate 协议
WKNavigationDelegate
主要处理页面跳转相关事件
//判断链接是否允许跳转- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;//拿到响应后决定是否允许跳转- (void)webView:(WKWebView *)webView decidePolicyForNavigationRe-sponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;//链接开始加载时调用- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation;//收到服务器重定向时调用- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation;//加载错误时调用- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error;//当内容开始到达主帧时被调用(即将完成)- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation;//加载完成- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation;//在提交的主帧中发生错误时调用- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error;//当webView需要响应身份验证时调用(如需验证服务器证书)- (void)webView:(WKWebView *)webView didReceiveAuthenticationChal-lenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable creden-tial))completionHandler;//当webView的web内容进程被终止时调用。(iOS 9.0之后)- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView API_AVAILABLE(macosx(10.11), ios(9.0));
WKUIDelegate 协议
WKUIDelegate
主要处理一些页面上的事件,如警告框、对话框等。
常用的方法:
//接收到警告面板- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler;//接收到确认面板- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;//接收到输入框- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable result))completionHandler;
四、WKWebView与JS的交互
交互方式
iOS 8.0 之前 用UIWebView
时,只能OC调用JS代码,但JS是无法直接调用OC代码,需要通过约定特殊请求,并通过UIWebView
的协议方法拦截请求的方式来实现JS对OC的调用。
但使用 WKWebView
就方便的多,可以直接添加对约定的ScriptMessage(直译为 脚本信息,本文暂定为JS事件)的监听,即可实现JS调用OC。
所有的操作都是通过WKUserContentController
来处理的
如何获取WKUserContentController
WKUserContentController
是 WKWebViewConfiguration
的属性,
而WKWebViewConfiguration
是 WKWebView
的属性(也就是在WKWebView
实例化的时候传入的configuration
)
WKUserContentController *conntentController = self.webView.configuration.userContentController;
下面将详细介绍WKUserContentController。
五、WKUserContentController & JS调用OC
/*! A WKUserContentController object provides a way for JavaScript to post messages to a web view. The user content controller associated with a web view is specified by its web view configuration. */WK_EXTERN API_AVAILABLE(macosx(10.10), ios(8.0))@interface WKUserContentController : NSObject <NSCoding>
WKUserContentController
提供了JavaScript
给Web view 发消息的途径
相关方法介绍
//添加ScriptMessage(JS事件)和处理者- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;//移除指定ScriptMessage(JS事件)监听- (void)removeScriptMessageHandlerForName:(NSString *)name;
JS调用OC
ScriptMessage(JS事件)的添加删除
首先在JS代码中加入对事先约定好的 ScriptMessage(JS事件)的调用
window.webkit.messageHandlers.<事件名>.postMessage(需要传递的数据)
同时OC端则需要加入对此JS事件的监听
例如:传递一个名为 @”closeWindow” 的消息
window.webkit.messageHandlers.closeWindow.postMessage()
OC端添加一个名为 @”closeWindow” 的 JS的监听
[conntentController addScriptMessageHandler:self name:@"closeWindow"];
这里就添加了对 @”closeWindow” 的监听。但是当截获 此JS事件的时候需要作何处理,则需要在对应的协议方法中实现,则scriptMessageHandler
需要实现协议WKScriptMessageHandler
会在稍后介绍。
移除对一个名为 @”closeWindow” 的JS事件的监听
[conntentController removeScriptMessageHandlerForName:@"closeWindow"];
WKScriptMessageHandler 协议
//当接收到一个ScriptMessage(JS事件)时调用- (void)userContentController:(WKUserContentController *)userContentController didRe-ceiveScriptMessage:(WKScriptMessage *)message;
例如:处理名为 @”closeWindow” 的事件
- (void)userContentController:(WKUserContentController *)userContentController didRe-ceiveScriptMessage:(WKScriptMessage *)message{ //message.name 为 ScriptMessage 的名称 if ([message.name isEqualToString:@"closeWindow"]) { //做处理 do something //message.body 为此 ScriptMessage 传递的消息内容 }}
六、OC调用JS
与UIWebView
一样WKWebView
可直接调用JS方法
WKWebView方法
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;
同样需要事先得知JS端的方法名和对应操作的key值
例如: 通知web某处理完成
约定的 JS函数名为 function ,需要执行一个约定好的操作名为 action,则调用如下
[self.webView evaluateJavaScript:@"function('action')" completionHandler:nil];
七、同步标题
有的时候 WKWebView
所在UIViewController
(视图控制器)是存在UINavigationController
导航控制器的, 这时可能需要根据跳转的网页而变化标题,这时只需要KVO WKWebView
的 title
即可,并将最新的title
赋值给 UIViewController
的 title
即可。
[self.webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL];
- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change context:(nullable void *)context{ if([keyPath isEqualToString:@"title"]){ self.navigationItem.title = self.webView.title; }}
- ios WKWebView 与 JS 交互实战技巧
- WKWebView与JS交互实战技巧之API介绍
- WKWebView与JS交互之实战技巧介绍
- WKWebView与JS交互实战技巧之API介绍
- iOS WKWebView 与 js 交互
- iOS WKWebView与JS交互
- iOS WKWebView js交互
- WKWebView与js交互
- WKWebView与JS交互
- WKWebView与JS交互
- WKWebView与js交互
- WKWebView与JS交互
- WKWebView与js交互
- WKWebView 与 JS 交互
- WKWebView与js交互
- iOS-WKWebView特性以及与JS交互的一些事
- iOS下OC与JS的交互(WKWebview-MessageHandler实现)
- iOS开发中的WKWebView与JS的交互
- ES6-正则的扩展-dotAll 模式
- 通讯概念(三)ip,mac,netmask,默认网关
- Selenium learning key points summary
- hibernate需要的jar包及其作用
- a64_7.1android平板更改状态栏底部导航栏navgationBar颜色
- ios WKWebView 与 JS 交互实战技巧
- swing重绘按钮为任意形状
- 使用GZIP解压缩数据,以及解决中文乱码
- tensorflow c/c++库使用方法
- Java 线程 4
- 拉里·埃里森亲自支招,数据库自动化之后,DBA何去何从?
- 关于ImageLoader的使用将图片改变为圆形
- 1190: [HNOI2007]梦幻岛宝珠
- Vue + ElementUI 手撸后台管理网站基本框架(二)权限控制