一、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 decidePolicyForNavigationResponse:(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 didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))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 didReceiveScriptMessage:(WKScriptMessage *)message;

例如:处理名为 @”closeWindow” 的事件

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(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;
}
}</nskeyvaluechangekey,></wkscriptmessagehandler></nscoding></wkuidelegate></wknavigationdelegate></webkit>

ios WKWebView 与 JS 交互实战技巧的更多相关文章

  1. iOS与JS交互实战篇(ObjC版)

    前言 ObjectiveC与Js交互是常见的需求,可对于新手或者所谓的高手而言,其实并不是那么简单明了.这里只介绍iOS7.0后出来的JavaScriptCore framework. 关于JavaS ...

  2. iOS webView与js交互在文本空格上输入文字

    项目要求:webview加载html网址,内容为填空题型文本,需要在横线上添加答案,并点击提交按钮后再将答案进行回显 正常加载的效果图片: 这个是用js交互后的效果图: 点击空格,输入想输入的答案,如 ...

  3. iOS WKWebView与JS的交互

    参考链接:https://www.jianshu.com/p/524bc8699ac2

  4. WKWebView与JS交互,UIWebView+JavascriptCore和JS交互

    最近一直在做有关Swift和JavaScript交互的程序,所以有关UIWebView和WKWebView在使用上的差别在此总结下: UIWebView: (1)创建 var webView: UIW ...

  5. iOS之与JS交互通信

    随着苹果SDK的不断升级,越来越多的新特性增加了进来,本文主要讲述从iOS6至今,Native与JavaScript的交互方法 一.UIWebview && iframe && ...

  6. WKWebView与Js交互

    首先打开webstorm,将最下面h5拷贝到html中.然后导入工程 #define kMessageHandlerName @"mymobile" 1.创建配置类 - (WKWe ...

  7. WKwebView与JS交互(h5主动)

    先:WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler // 创建一个webiview的配置项 WKWebViewConfiguratio ...

  8. andriod/ios webview与js交互 html_demo

    <html> <head> <title>测试</title> </head> <body> <h3>Android ...

  9. WKWebView与js交互中产生的内存泄漏

    最近开发中突然发现富文本帖子详情内存没有释放掉,找了好久问题都没找到,终于今天发现了问题,先上一点代码片段 WKWebViewConfiguration *configuration = [[WKWe ...

随机推荐

  1. Caffe框架,训练model并测试数据

    1. 训练model #!/usr/bin/env sh ./build/tools/caffe train --solver=examples/focal_length/focal_solver.p ...

  2. pig的limit无效(返回所有记录)sample有效

    pig中,limit可以取样少部分数据,但有很多问题,比如数据不能少于10条,否则返回全部. 今天又遇到另一个问题: group后的数据,limit无效:也就是group后的数据,不能用limit,估 ...

  3. chrome "Provisional headers are shown"

    我的问题的,每次打开浏览器,点开有视频的页面(云平台的存储),然后当视频还没有加载完,就马上关闭,连续操作很多次(测试的暴力测试把),F12查看就有很多很多在加载中的连接,因为连续点击太多次了,第一个 ...

  4. React Native之hellWord

    初始化项目工程 进入自己的工作空间然后shift+鼠标右键打开命令行窗口执行如下命令创建RN工程HelloWorld: 然后使用Android Studio打开AVD Manager创建模拟器,在打开 ...

  5. Android存储系统的架构与设计

    一.概述 本文讲述Android存储系统的架构与设计,基于Android 6.0的源码,涉及到最为核心的便是MountService和Vold这两个模块以及之间的交互.为了缩减篇幅,只展示部分核心代码 ...

  6. Dynamics CRM 2011/2013 DeveloperToolkit的使用

    Dynamic CRM 2011的SDK中提供了一个叫DeveloperToolkit的工具,他的用途官方说明说的很明确,能方便开发者在VS中直接部署webresource.plugin.workfl ...

  7. Dynamics CRM2011 同一个FORM表单同一个字段可以摆放多次

    这是一个很细微的问题,细微到很容易被忽略(可能其他人没有但我确实是忽略了) 红框中的勾默认是勾选的,可能有人会像我一样,从没关心过这个地方还有个勾也从没关心过要把这个勾去掉,所以在表单上A.B两个节中 ...

  8. Graph Cut and Its Application in Computer Vision

    Graph Cut and Its Application in Computer Vision 原文出处: http://lincccc.blogspot.tw/2011/04/graph-cut- ...

  9. 【一天一道LeetCode】#4 Median of Two Sorted Arrays

    一天一道LeetCode (一)题目 There are two sorted arrays nums1 and nums2 of size m and n respectively. Find th ...

  10. FFMPEG结构体分析:AVCodecContext

    注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrame FFMPEG结构体分析:AVFormatContext FFMPEG结构体分析:AVCodecConte ...