app开发中一些重运营业务大多都通过web来实现快速迭代,iOS可以使用UIWebView、WKWebView实现Native和Web的交互。之前在项目中负责过WebView模块,所以在这里做一些WebView的总结,主要从包括以下一些点:
1.为什么要封装WebView
2.JSBridge
3.离线包
4.WKWebView
为什么要封装WebView
我们项目中把WebView封装成了一个ViewController,可能很多人会觉得iOS里要现实web不就直接用UIWebView和WKWebView吗,为什么还要进行封装,我觉的主要是从下面点来考虑:
1.统一ui样式。包括导航条,进度条,错误页面等,避免重复造轮子。
2.封装基础能力。抽象业务无关的基础能力,比如导航条设置(更改导航条颜色,设置ButtonItem)、cookie设置、UA设置、JSBridge、数据上报等
3.hook request。进行安全校验,鉴权处理
JSBridge
iOS SDK 直接支持native调用js,UIWebView调用stringByEvaluatingJavaScriptFromString,WKWebView调用evaluateJavaScript: completionHandler
iOS SDK 没有天生支持 js 和 native 相互调用,都是自己实现一套调用机制,目前主要有下面几种方法:
1.通过iframe
通过创建iframe,然后在webview delegate hook请求
2.JavaScriptCore
iOS 7开始引进了JavaScriptCore可以方便高效实现JS和oc之间的调用
3.WKScriptMessageHandler
WKWebView可以使用WKScriptMessageHandler来实现JS调用oc方法
离线包
主要是通过NSURLProtocol hook request来实现离线包,严格来说跟WebView没半毛钱关系。
WKWebView
iOS8引入了WKWebView,WKWebView使用独立的进程渲染web,解决了UIWebView内存泄漏和crash率高的问题,但是理想虽然很丰满,现实却很骨感,实际使用WKWebView还是会有很多问题。之前在项目中做过切换WKWebView,刚好可以总结下遇到的问题和解决方法,主要有下面问题:
1.没法直接设置Cookie
WKWebView不使用NSHTTPCookieStorage,所以没法直接设置Cookie,app中web请求一般都会通过cookie带登录态到后台,如果没法设置cookie的话是没法正常工作的。尝试过几种方案后我们最终是通过request header把cookie带到server,同时通过WKUserScript把cookie种到本地。
2.不经过URL Load System
这样就不能使用NSURLProtocol来实现离线包和定制request了