H5 js与iOS WKWebView交互

WKWebView的优势

1 更多的支持HTML5的特性
2 官方宣称的高达60fps的滚动刷新率以及内置手势
3 将UIWebViewDelegate与UIWebView拆分成了14类与3个协议,以前很多不方便实现 的功能得以实现
4 Safari相同的JavaScript引擎
5 占用更少的内存

    WKBackForwardList: 之前访问过的 web 页面的列表,可以通过后退和前进动作来访问到。
    WKBackForwardListItem: webview 中后退列表里的某一个网页。
    WKFrameInfo: 包含一个网页的布局信息。
    WKNavigation: 包含一个网页的加载进度信息。
    WKNavigationAction: 包含可能让网页导航变化的信息,用于判断是否做出导航变化。
    WKNavigationResponse: 包含可能让网页导航变化的返回内容信息,用于判断是否做出导航变化。
    WKPreferences: 概括一个 webview 的偏好设置。
    WKProcessPool: 表示一个 web 内容加载池。
    WKUserContentController: 提供使用 JavaScript post 信息和注射 script 的方法。
    WKScriptMessage: 包含网页发出的信息。
    WKUserScript: 表示可以被网页接受的用户脚本。
    WKWebViewConfiguration: 初始化 webview 的设置。
    WKWindowFeatures: 指定加载新网页时的窗口属性。
协议
    WKNavigationDelegate: 提供了追踪主窗口网页加载过程和判断主窗口和子窗口是否进行页面加载新页面的相关方法。
    WKScriptMessageHandler: 提供从网页中收消息的回调方法。
    WKUIDelegate: 提供用原生控件显示网页的方法回调。
加载方式
 //方式一
 WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
 [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];
 [self.view addSubview:webView];

 //方式二
 WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc] init];
 webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:configuration];
 [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];
 [self.view addSubview:webView];
协议方法介绍
 #pragma mark - WKNavigationDelegate
 // 页面开始加载时调用
 - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {

 }
 // 当内容开始返回时调用
 - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {

 }
 // 页面加载完成之后调用
 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {

 }
 // 页面加载失败时调用
 - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation {

 }
 // 接收到服务器跳转请求之后调用
 - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {

 }
 // 在收到响应后,决定是否跳转
 - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {

 NSLog(@"%@",navigationResponse.response.URL.absoluteString);
 //允许跳转
 decisionHandler(WKNavigationResponsePolicyAllow);
 //不允许跳转
 //decisionHandler(WKNavigationResponsePolicyCancel);
 }
 // 在发送请求之前,决定是否跳转
 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {

 NSLog(@"%@",navigationAction.request.URL.absoluteString);
 //允许跳转
 decisionHandler(WKNavigationActionPolicyAllow);
 //不允许跳转
 decisionHandler(WKNavigationActionPolicyCancel);
 }
 #pragma mark - WKUIDelegate
 // 创建一个新的WebView
 - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
 return [[WKWebView alloc]init];
 }
 // 输入框
 - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler {
 completionHandler(@"http");
 }
 // 确认框
 - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler {
 completionHandler(YES);
 }
 // 警告框
 - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
 NSLog(@"%@",message);
 completionHandler();
 }

Objc与JS的交互

WKWebView的 UIDelegate 提供了三个协议方法, 可以让前端很方便的拦截JS的alert, confirm, prompt方法。除此之外,Objc和JS可以按照如下方法互相调用。

1. Objc 调用JS

当iOS端想传一些数据给JS,需要调用下面方法来发送:

- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;

//例如Objc调用JS的方法 setName

[self.webView evaluateJavaScript:@"setname('张三')" completionHandler:^(id obj, NSError *error) {
        
}];

//此处 setname为JS定义的方法名, 内部 ‘张三’为传给JS的参数。 如果setname方法需要传入一个json或者array等非字符参数, 需要用format方法将其转为string类型,在调用evaluate方法。例如

NSString * para = [NSString stringWithFormat:@"setname('%@')", json];
[self.webView evaluateJavaScript:para completionHandler:^(id obj, NSError *error) {
        
}];
2. JS调用Objc

当JS端想传一些数据给Objc,需要调用下面方法来发送,此时就要用到WKScriptMessageHandler了:

//首先.m中加入属性
 @property (nonatomic ,strong)WKUserContentController * userCC;

//1 遵循WKScriptMessageHandler协议
//2 初始化
   WKWebViewConfiguration * config = [[WKWebViewConfiguration alloc]init];

 self.wkWebViw = [[WKWebView alloc]initWithFrame:self.view.bounds configuration:config];

 [self.wkWebViw loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.webPageUrl]]];

 [self.view addSubview:self.wkWebViw];

 self.userCC = config.userContentController;

 [self.userCC addScriptMessageHandler:self name:@"callOSX"];

 //此处相当于监听了JS中callFunction这个方法

 [self.userCC addScriptMessageHandler:self name:@"callFunction"];

 //当JS发出callFunction这个方法指令的时候, WKScriptMessageHandler的协议方法中我们就会收到这个消息

 #pragma mark  WKScriptMessageHandler delegate
 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
//这个回调里面, message.name代表方法名(‘本例为 callFunction’), message.body代表JS给我们传过来的参数
    if ([message.name isEqualToString:@"callFunction"]) {
        //NSLog(@"JS发来了消息:%@", message.body);
    }
 }

//最后, VC销毁的时候一定要把handler移除
- (void)dealloc {
    [_userContentController removeScriptMessageHandlerForName:@"callFunction"];
}

对应的JS代码




你可能感兴趣的:(H5 js与iOS WKWebView交互)