WKWebView 的使用和封装
前言
项目中有个新闻资讯模块展示公司和相关行业的最新动态。
这个部分基本是以展示网页为主,内部可能会有一些 native 和 JS 代码的交互。
因为是新项目,所以决定采用 iOS 8 中新出的 WebKit。
本文是对 WebKit 框架中 WKWebView 的一些学习和封装
UIWebView 和 WKWebView
这两者都是 iOS 中展示 web 相关的组件。前者 iOS 2.0 就有了,后者是 iOS 8.0 时候新加的。
网络中关于两者的差异和性能对比分析很多,这里不再赘述。只是说明一下苹果文档中的重要提示以及自己需要功能的实现:
官方文档中重要提示
文档中主要说了以下几点:
- iOS 8 之后,应该用 WKWebView 代替 UIWebView。并可以设置
WKPreferences
的javaScriptEnabled
属性决定是否支持 web 内容执行 JavaScript 代码 - iOS 10 之后必须在 info.plist 文件中包含要访问数据的描述。对于图库的访问必须包含
NSPhotoLibraryUsageDescription
和NSCameraUsageDescription
否则会直接 crash - 加载本地 HTML 文件使用:
loadHTMLString:baseURL:
方法 - 加载网络内容使用 :
loadRequest:
方法 stopLoading
方法用来结束加载。loading
属性查看WK进程中是否加载中goBack
和goForward
方法可用于 WKWebView 的前进后退.canGoBack
和canGoForward
属性来查看是否能前进后退- 通常WKWebView会自动识别电话号码,并把它设置成可打电话的链接。如果不用这个功能: 设置
dataDetectorTypes
属性中UIDataDetectorTypes
的位字段不包含UIDataDetectorTypePhoneNumber
. scalesPageToFit
属性用于第一次加载网页内容时候设置是否可以使用手势改变网页缩放。 设置后用户就可以手势缩放网页大小- 记录网页加载网络内容可以设置WKWebView 的
delegate
并遵守UIWebViewDelegate
协议 - 不要在 网页中嵌入 UIScrollView 及其子类,这样会导致手势等行为混乱
有了基本的概念,就可以去看一下 WKWebView 的具体文档了。如果怕官方文档麻烦也可以直接看网络上别人整理好的网络整理。
下面是我整理的 WebView 和 H5 调用逻辑图:
特别说明一点:
|
功能需求
对于项目而言,网页功能无需太多,主要满足以下几点
基本展示功能
- 导航栏下显示加载进度条
- 导航栏 title 展示网页内容当前 title
- 网页内容的刷新、前进、后退
- 网页内容加载、刷新过程中 HUD 提示
JS和OC交互功能:交互的数据格式和方法名等需要和H5端具体协调
- App内登录后,访问 web 需要对应用户token
- 网页中点击超链接,新开页面处理,同上也需要拦截新URL请求并补全token参数
- 跟JS交互中对JS返回值的处理
- 简单JS代码注入,如资讯内容底部加一些赞和分享等功能<曾经就有接口只返回一段JS>
以上这些基本功能中基本展示功能都比较简单,和JS交互的部分需要和 H5 端小伙伴共同定义数据结构和互调的方法名、参数等。所以需要具体问题具体分析。项目以我自己 Demo 为例说一下。
功能实现
为实现功能主要封装了三个类
|
XYWKWebView 核心功能
加载本地HTML文件
|
实现代码
|
加载网络内容
|
实现代码
|
XYWKWebViewController 核心功能
这是一个 Controller,建议创建新的Controller继承XYWKWebViewController 来使用,这样可以把不同的页面区分开,每个页面加载的url和相关的业务逻辑都可以单独处理,代码易读,也容易维护。如果项目后期添加功能也好处理
XYWKWebViewController主要完成了对一些功能的封装,比如进度条、页面title以及 webView 的生命周期。
进度条和title都是通过KVO实现
|
设置title 和 progressView 直接是自己简单写了一个 View
|
OC 与 JS 之间交互的处理
这部分是可定制化功能最多的,遇到的问题也是最多的。WKWebView 和 JS 之间的交互需要设置 ScriptMessageHandler 如下。
|
然后实现 WKScriptMessageHandler 代理
|
其中自定义的 XYScriptMessage 如下
|
同时提供delegate方法供XYWKWebViewController实现
|
使用方法
一个提供四类使用功能,使用方法建议直接继承 XYWKWebViewController。
|
具体见Demo
遇到的问题
HTML 中超链接,需要打开新页面的“_blank”处理
小结
WebKit 的小封装能实现目前所需功能,但很多内容还需要在需要的时候去探究,希望能帮到同样学习的小伙伴。
如果看完有收获,不妨点个赞,让我也更有分享的动力!