ios下OC与JS交互之WKWebView
上一篇文章我们使用了JavaScriptCore框架重写了之前的示例,iOS8苹果偏爱HTML5,重构了UIWebVIew,给我们带来了WKWebView,使其性能、稳定性、功能大幅度提升,也更好的支持了HTML5的新特性。这篇文章就们就拿WKWebView来小试牛刀
一、WKWebViewFramework
WKWebView的14个类与3个协议:
WKBackForwardList:之前访问过的web页面的列表,可以通过后退和前进动作来访问到。
WKBackForwardListItem:webview中后退列表里的某一个网页。
WKFrameInfo:包含一个网页的布局信息。
WKNavigation:包含一个网页的加载进度信息。
WKNavigationAction:包含可能让网页导航变化的信息,用于判断是否做出导航变化。
WKNavigationResponse:包含可能让网页导航变化的返回内容信息,用于判断是否做出导航变化。
WKPreferences:概括一个webview的偏好设置。
WKProcessPool:表示一个web内容加载池。
WKUserContentController:提供使用JavaScriptpost信息和注射script的方法。
WKScriptMessage:包含网页发出的信息。
WKUserScript:表示可以被网页接受的用户脚本。
WKWebViewConfiguration:初始化webview的设置。
WKWindowFeatures:指定加载新网页时的窗口属性。
WKWebsiteDataStore:包含网页数据存储和查找。
WKNavigationDelegate:提供了追踪主窗口网页加载过程和判断主窗口和子窗口是否进行页面加载新页面的相关方法。
WKUIDelegate:提供用原生控件显示网页的方法回调。
WKScriptMessageHandler:提供从网页中收消息的回调方法。
二、WKWebView中的三个代理方法
1.WKNavigationDelegate
该代理提供的方法,可以用来追踪加载过程(页面开始加载、加载完成、加载失败)、决定是否执行跳转。
//页面开始加载时调用 -(void)webView:(WKWebView*)webViewdidStartProvisionalNavigation:(WKNavigation*)navigation; //当内容开始返回时调用 -(void)webView:(WKWebView*)webViewdidCommitNavigation:(WKNavigation*)navigation; //页面加载完成之后调用 -(void)webView:(WKWebView*)webViewdidFinishNavigation:(WKNavigation*)navigation; //页面加载失败时调用 -(void)webView:(WKWebView*)webViewdidFailProvisionalNavigation:(WKNavigation*)navigation;
页面跳转的代理方法有三种,分为(收到跳转与决定是否跳转两种)
//接收到服务器跳转请求之后调用 -(void)webView:(WKWebView*)webViewdidReceiveServerRedirectForProvisionalNavigation:(WKNavigation*)navigation; //在收到响应后,决定是否跳转 -(void)webView:(WKWebView*)webViewdecidePolicyForNavigationResponse:(WKNavigationResponse*)navigationResponsedecisionHandler:(void(^)(WKNavigationResponsePolicy))decisionHandler; //在发送请求之前,决定是否跳转 -(void)webView:(WKWebView*)webViewdecidePolicyForNavigationAction:(WKNavigationAction*)navigationActiondecisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler;
2.WKUIDelegate
创建一个新的WKWebView
//创建一个新的WebView -(WKWebView*)webView:(WKWebView*)webViewcreateWebViewWithConfiguration:(WKWebViewConfiguration*)configurationforNavigationAction:(WKNavigationAction*)navigationActionwindowFeatures:(WKWindowFeatures*)windowFeatures;
剩下三个代理方法全都是与界面弹出提示框相关的,针对于web界面的三种提示框(警告框、确认框、输入框)分别对应三种代理方法。
//界面弹出警告框 -(void)webView:(WKWebView*)webViewrunJavaScriptAlertPanelWithMessage:(NSString*)messageinitiatedByFrame:(void(^)())completionHandler; //界面弹出确认框 -(void)webView:(WKWebView*)webViewrunJavaScriptConfirmPanelWithMessage:(NSString*)messageinitiatedByFrame:(WKFrameInfo*)framecompletionHandler:(void(^)(BOOLresult))completionHandler; //界面弹出输入框 -(void)webView:(WKWebView*)webViewrunJavaScriptTextInputPanelWithPrompt:(NSString*)promptdefaultText:(nullableNSString*)defaultTextinitiatedByFrame:(WKFrameInfo*)framecompletionHandler:(void(^)(NSString*__nullableresult))completionHandler;
3.WKScriptMessageHandler
这个协议中包含一个必须实现的方法,这个方法是native与web端交互的关键,它可以直接将接收到的JS脚本转为OC或Swift对象。
//从web界面中接收到一个脚本时调用 -(void)userContentController:(WKUserContentController*)userContentControllerdidReceiveScriptMessage:(WKScriptMessage*)message;
三、使用WKWebView重写
这里我们和之前的界面做了一点改动,之前OC调用JS的时候是进行弹框处理,这里我在写的时候,很郁闷,方法可以调用过去,但是唯独js的alert方法调用没有效果,所以这里采用了输出到div的形式,并增加了一个clear按钮
WKWebView不支持nib文件,所以这里需要使用代码初始化并加载WebView
WKWebViewConfiguration*config=[[WKWebViewConfigurationalloc]init]; config.preferences.minimumFontSize=18; self.wkWebView=[[WKWebViewalloc]initWithFrame:CGRectMake(0,0,self.view.bounds.size.width,self.view.bounds.size.height/2)configuration:config]; [self.viewaddSubview:self.wkWebView]; NSString*filePath=[[NSBundlemainBundle]pathForResource:@"index"ofType:@"html"]; NSURL*baseURL=[[NSBundlemainBundle]bundleURL]; [self.wkWebViewloadHTMLString:[NSStringstringWithContentsOfFile:filePathencoding:NSUTF8StringEncodingerror:nil]baseURL:baseURL];
OC端:
//1.JS调用OC添加处理脚本 [userCCaddScriptMessageHandler:selfname:@"showMobile"]; [userCCaddScriptMessageHandler:selfname:@"showName"]; [userCCaddScriptMessageHandler:selfname:@"showSendMsg"]; //在代理方法中处理对应事件 -(void)userContentController:(WKUserContentController*)userContentControllerdidReceiveScriptMessage:(WKScriptMessage*)message{ NSLog(@"%@",NSStringFromSelector(_cmd)); NSLog(@"%@",message.body); if([message.nameisEqualToString:@"showMobile"]){ [selfshowMsg:@"我是下面的小红手机号是:18870707070"]; } if([message.nameisEqualToString:@"showName"]){ NSString*info=[NSStringstringWithFormat:@"你好%@,很高兴见到你",message.body]; [selfshowMsg:info]; } if([message.nameisEqualToString:@"showSendMsg"]){ NSArray*array=message.body; NSString*info=[NSStringstringWithFormat:@"这是我的手机号:%@,%@!!",array.firstObject,array.lastObject]; [selfshowMsg:info]; } } //2.native调用js -(IBAction)btnClick:(UIButton*)sender{ if(!self.wkWebView.loading){ if(sender.tag==123){ [self.wkWebViewevaluateJavaScript:@"alertMobile()"completionHandler:^(id_Nullableresponse,NSError*_Nullableerror){ //TODO NSLog(@"%@%@",response,error); }]; } if(sender.tag==234){ [self.wkWebViewevaluateJavaScript:@"alertName('小红')"completionHandler:nil]; } if(sender.tag==345){ [self.wkWebViewevaluateJavaScript:@"alertSendMsg('18870707070','周末爬山真是件愉快的事情')"completionHandler:nil]; } }else{ NSLog(@"theviewiscurrentlyloadingcontent"); } }
JS端:
functionclear(){ document.getElementById('mobile').innerHTML='' document.getElementById('name').innerHTML='' document.getElementById('msg').innerHTML='' } //OC调用JS的方法列表 functionalertMobile(){ //这里已经调用过来了但是搞不明白为什么alert方法没有响应 //alert('我是上面的小黄手机号是:13300001111') document.getElementById('mobile').innerHTML='我是上面的小黄手机号是:13300001111' } functionalertName(msg){ //alert('你好'+msg+',我也很高兴见到你') document.getElementById('name').innerHTML='你好'+msg+',我也很高兴见到你' } functionalertSendMsg(num,msg){ //window.alert('这是我的手机号:'+num+','+msg+'!!') document.getElementById('msg').innerHTML='这是我的手机号:'+num+','+msg+'!!' } //JS响应方法列表 functionbtnClick1(){ window.webkit.messageHandlers.showMobile.postMessage(null) } functionbtnClick2(){ window.webkit.messageHandlers.showName.postMessage('xiao黄') } functionbtnClick3(){ window.webkit.messageHandlers.showSendMsg.postMessage(['13300001111','GoClimbingThisWeekend!!!']) }
四、后记
至此,整个系列的示例已完成,过程中收货颇丰。每篇文章都会对知识点进行总结,在文章末尾给出示例DEMO的地址。
示例DEMO:OC-JS-WKWebView_jb51.rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。