摘自一篇有用的WKWebView的JS交互文章

优点:WebKit 使用Nitro JavaScript引擎,webview可以和Safari加载一样快。加载网页占用的内存大大优化。高达60fps的滚动刷新频率及内置手势。开放了更多API给开发者(14个类、3个协议);

使用:首先引入库 

#import  <WebKit/WebKit.h>

初始化:WKWebViewConfiguration class wkwebview的基本配置类 

    WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc]init]; 先实例化配置类 以前UIWebView的属性有的放到了这里

   _wkwebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0.0f, screen_width, screen_height) configuration:configuration];


新的属性:

    _wkwebView.allowsBackForwardNavigationGestures =YES;//打开网页间的滑动返回

    _wkwebView.allowsLinkPreview = YES;//允许预览链接

        backForwardList 中包含backList(访问过未返回的地址) forwardList(访问过已返回的地址)currentItem(当前访问的地址)


   wkwebview提供了KVO属性 可以用来获取加载进度(estimatedProgress) URL(URL)、TITLE(title)是否变化、是否可以前进或后退

    [_wkwebView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];//注册observer拿到加载进度


wkwebview除了后退:goBack 前进: goForward 方法外 还提供了reload方法 刷新当前页面 以及stopLoading 停止刷新

加载h5页面和UIWebView相似:[_wkwebView loadRequest:[NSURLRequest requestWithURL:url]];

代理:


//WKNavigationDelegate


//发送请求前决定是否允许跳转

/*

 typedef NS_ENUM(NSInteger, WKNavigationActionPolicy) {

 WKNavigationActionPolicyCancel,不允许

 WKNavigationActionPolicyAllow, 允许

 } NS_ENUM_AVAILABLE(10_10, 8_0);

 */

发生请求前是否允许跳转

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler

{

    decisionHandler(WKNavigationActionPolicyAllow);

    NSLog(@"发送请求前 allow跳转");

}


//接收到服务器响应后决定是否允许跳转

- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;

{

    decisionHandler(WKNavigationResponsePolicyAllow);

    NSLog(@"接收到响应后 allow跳转");


}


//接收到服务器跳转响应后调用

-(void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation

{

    NSLog(@"tiaozhuan");


}


//开始加载页面

-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation;

{

    NSLog(@"开始加载页面");

}


//加载页面数据完成

-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation

{

    NSLog(@"加载页面完成");

    NSLog(@"backlist ===%@",webView.backForwardList.backList);访问过未返回的页面

    NSLog(@"forwordlst==%@",webView.backForwardList.forwardList);访问过已返回的页面

    NSLog(@“url===%@",webView.backForwardList.currentItem.URL);当前访问的页面

    在这里可以拿到web页的相关信息 做一些操作   

}


//接收数据

-(void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation

{

    NSLog(@"接收数据中");

}


//加载失败

- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error;

{

    NSLog(@"页面加载失败");

}

//在这个方法里实现注册的供js调用的oc方法

-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message

{

      js native 交互

}


WKUIDelegate 页面中有调用了js的alert、confirm、prompt方法,应该实现下面这几个代理方法,然后在原来这里调用native的弹出窗,因为使用WKWebView后,HTML中的alert、confirm、prompt方法调用是不会再弹出窗口了,只是转化成ios的native回调代理方法(没咋用)。


JS NATIVE 交互:wkwebview提供了API实现js交互 不需要借助JavaScriptCore或者webJavaScriptBridge。使用WKUserContentController实现js native交互

oc代码:

 首先需要在实例化WKWebViewConfiguration时 实例 WKUserContentController类并将其赋值给confiuration的属性:userContentController。

WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc]init];

    //注册供js调用的方法

    userContentController =[[WKUserContentController alloc]init];

    [userContentController addScriptMessageHandler:self  name:@“aaa”];//注册一个name为aaa的js方法

    configuration.userContentController = userContentController;

    configuration.preferences.javaScriptEnabled = YES;打开JavaScript交互 默认为YES

    _wkwebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0.0f, screen_width, screen_height) configuration:configuration];

实现WKScriptMessageHandler的协议方法

-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message

{

userContentController 注册message的WKUserContentController;

message:js传过来的数据

id body:消息携带的信息 Allowed types are NSNumber, NSString, NSDate, NSArray, NSDictionary, and NSNull.

NSString *name:消息的名字 如aaa

 //message.name  js发送的方法名称

    if([message.name  isEqualToString:@"aaa"])

    {

        NSString * body = [message.body objectForKey:@“body"];

     在这里写oc 实现协议的native方法 }

}



前端h5代码:前端需要用 window.webkit.messageHandlers.注册的方法名.postMessage({body:传输的数据} 来给native发送消息

例如:

function secondClick() {

    window.webkit.messageHandlers.aaa.postMessage({body: 'call js alert in js'});

}


**重要 如果注册了方法    [userContentController addScriptMessageHandler:self  name:@“aaa"];

会导致hangler一直被引用 导致不走Delloc web页面无法释放 所以要在-(void)viewDidDisappear:(BOOL)animated中将messageHandler移除

    [userContentController removeScriptMessageHandlerForName:@“aaa"]; 关闭web页时会释放内存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本demo是WKWebView的基本使用和交互 ,实现了原生调用js的方法、js调用原生的方法、通过拦截进行交互的方法;修改内容 加入沙盒 / /加载沙盒 不带参数 // NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); // NSString * path = [paths objectAtIndex:0]; // path = [path stringByAppendingString:[NSString stringWithFormat:@"/app/html/index.html"]]; // NSURL *url = [NSURL URLWithString:[[NSString stringWithFormat:@"file://%@",path] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]] relativeToURL:[NSURL fileURLWithPath:NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject]]; // [self.wkView loadFileURL:url allowingReadAccessToURL:[NSURL fileURLWithPath: [paths objectAtIndex:0]]]; // 带参数 /* NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString * path = [paths objectAtIndex:0]; path = [path stringByAppendingString:[NSString stringWithFormat:@"/app/html/index.html"]]; NSURL * url = [NSURL fileURLWithPath:path isDirectory:NO]; NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO]; [queryItemArray addObject:[NSURLQueryItem queryItemWithName:@"version" value:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]]]; [urlComponents setQueryItems:queryItemArray]; [self.wkView loadFileURL:urlComponents.URL allowingReadAccessToURL:[NSURL fileURLWithPath: [paths objectAtIndex:0]]]; */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值