kidd风的IOS日志之从UIWebView到WKWebView
2016-03-12 17:35
501 查看
引言
①本文章适合有 UIWebView 基础的人看,如果实在没用过的话,至少你要知道 UIWebView 是个什么东西。
② UIWebView 和 WKWebView 的区别
WKWebView 更快(占用内存可能只有 UIWebView 的1/3~1/4),没有缓存,更为细致地拆分了 UIWebViewDelegate 中的方法。
想要了解更多关于 WKWebView 的特性的,可以自行 Google,这里你可以简单地把它当做是轻量级的 UIWebView。
③为什么现在是时候从 UIWebView 迁移到 WKWebView 了:
截止到我写这篇文章的时候,据 mixpanel 的数据,iOS 9 占有率已达 58.55%,iOS 8 占有率达到了 34.78%,iOS 7 及更早版本是 6.66%,而那 6.66% 应该大部分都是对手机使用极度不频繁的人。所以从现在开始,再开发 App 只兼容 iOS 8 和 iOS 9 两个版本就可以了(如果你的产品对覆盖率要求不是很苛刻的话)。WKWebView 是 iOS 8 之后才有的 WebKit 中的内容,所以之前我们要同时兼容 iOS 7 和 iOS 8 的时候,可以推辞说 UIWebView
和 WKWebView 一起做太麻烦了,现在可没有理由拒绝新东西了。
在 WKWebView 中,UIWebViewDelegate 与 UIWebView 被重构成了14类与3个协议,下面给出一些在 UIWebView 中常用的方法的 WKWebView 版本。
以上方法分别存在于 UIWebViewDelegate 和 WKNavigationDelegate 中。
如果你之前只是用到了以上列出的 UIWebViewDelegate 中的几个方法,那么只是简单地换一个方法名,让你的 ViewController 继承 WKNavigationDelegate ,继续用就可以了。想要更多内容可以自己用 cmd键+鼠标左击『WKNavigationDelegate』通过 Xcode 查看。
要注意的是
下面的示例代码用于从 WKWebView 中获取网页中的文本。
可能你也注意到了,把 JS 脚本注入到 WebView 的途径是初始化一个 WebView,所以你需要在 WebView 初始化之前写好自己的脚本。当然如果你不需要 JS 交互,直接用一个 frame 来初始化 WebView,去掉 configuration 参数就好了。
然而,我们如何拿到从 WKWebView 中抓取到的文本呢(通过 document.body.innerText 这一句)?
如上面所说,让你的 ViewController 在继承了 WKNavigationDelegate 之后再继承一下 WKScriptMessageHandler 。然后实现 WKNavigationDelegate 中唯一的一个方法:
乍一看这里可能会有疑惑:我们给 WKWebView 绑定了 WKNavigationDelegate,但是 WKScriptMessageHandler 并没有提供代理方法啊。其实与此相对应的过程出现在上一段代码中的第5行:
①本文章适合有 UIWebView 基础的人看,如果实在没用过的话,至少你要知道 UIWebView 是个什么东西。
② UIWebView 和 WKWebView 的区别
WKWebView 更快(占用内存可能只有 UIWebView 的1/3~1/4),没有缓存,更为细致地拆分了 UIWebViewDelegate 中的方法。
想要了解更多关于 WKWebView 的特性的,可以自行 Google,这里你可以简单地把它当做是轻量级的 UIWebView。
③为什么现在是时候从 UIWebView 迁移到 WKWebView 了:
截止到我写这篇文章的时候,据 mixpanel 的数据,iOS 9 占有率已达 58.55%,iOS 8 占有率达到了 34.78%,iOS 7 及更早版本是 6.66%,而那 6.66% 应该大部分都是对手机使用极度不频繁的人。所以从现在开始,再开发 App 只兼容 iOS 8 和 iOS 9 两个版本就可以了(如果你的产品对覆盖率要求不是很苛刻的话)。WKWebView 是 iOS 8 之后才有的 WebKit 中的内容,所以之前我们要同时兼容 iOS 7 和 iOS 8 的时候,可以推辞说 UIWebView
和 WKWebView 一起做太麻烦了,现在可没有理由拒绝新东西了。
正文
常用代理方法
在 WKWebView 中,UIWebViewDelegate 与 UIWebView 被重构成了14类与3个协议,下面给出一些在 UIWebView 中常用的方法的 WKWebView 版本。//准备加载页面 [code]UIWebViewDelegate - webView:shouldStartLoadWithRequest:navigationType
WKNavigationDelegate - webView:didStartProvisionalNavigation:
//已开始加载页面,可以在这一步向view中添加一个过渡动画 [code]UIWebViewDelegate - webViewDidStartLoad:
WKNavigationDelegate - webView:didCommitNavigation:
//页面已全部加载,可以在这一步把过渡动画去掉 [code]UIWebViewDelegate - webViewDidFinishLoad:
WKNavigationDelegate - webView:didFinishNavigation:
//加载页面失败 [code]UIWebViewDelegate - webView:didFailLoadWithError:
WKNavigationDelegate - webView:didFailNavigation:withError:
WKNavigationDelegate - webView:didFailProvisionalNavigation:withError:
以上方法分别存在于 UIWebViewDelegate 和 WKNavigationDelegate 中。
如果你之前只是用到了以上列出的 UIWebViewDelegate 中的几个方法,那么只是简单地换一个方法名,让你的 ViewController 继承 WKNavigationDelegate ,继续用就可以了。想要更多内容可以自己用 cmd键+鼠标左击『WKNavigationDelegate』通过 Xcode 查看。
要注意的是
webview.delegate = self需要改写为
webview.navigationDelegate = self。
JS交互
在 UIWebView 中,一句简单的webView.stringByEvaluatingJavaScriptFromString()就可以用 JS 脚本操纵 WebView,在 WKWebView 中,我们可能需要用到
WKScriptMessageHandler这个协议中的
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage)方法。
下面的示例代码用于从 WKWebView 中获取网页中的文本。
let js = "window.webkit.messageHandlers.observe.postMessage(document.body.innerText);" // 注意这里的observe字段是自己写的,不是固定的写法,参考第6行 let script = WKUserScript(source: js, injectionTime: WKUserScriptInjectionTime.AtDocumentEnd, forMainFrameOnly: true) // 这里的 AtDocumentEnd 字段是指网页中的内容加载完毕后再插入 JS 脚本,你也可以选择 AtDocumentStart,在 document element 刚刚创建时就插入脚本,看具体需求 let config = WKWebViewConfiguration() config.userContentController.addUserScript(script) config.userContentController.addScriptMessageHandler(self, name: "observe") // 对应第一行 JS 脚本中的observe字段 //初始化WKWebView let webview = WKWebView( frame: CGRectMake(0, 0, self.view.frame.width, self.view.frame.height), configuration: config) webview.navigationDelegate = self self.view.addSubview(webview) //加载网页 webview.loadRequest(NSURLRequest(URL: NSURL(string: "http://www.jianshu.com")!))
可能你也注意到了,把 JS 脚本注入到 WebView 的途径是初始化一个 WebView,所以你需要在 WebView 初始化之前写好自己的脚本。当然如果你不需要 JS 交互,直接用一个 frame 来初始化 WebView,去掉 configuration 参数就好了。
然而,我们如何拿到从 WKWebView 中抓取到的文本呢(通过 document.body.innerText 这一句)?
如上面所说,让你的 ViewController 在继承了 WKNavigationDelegate 之后再继承一下 WKScriptMessageHandler 。然后实现 WKNavigationDelegate 中唯一的一个方法:
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage){ let str:NSString = message.body as! NSString // 因为我们抓取到的是文本,这里把 message.body 强制转换为 NSString,如果你通过 JS 拿到的是其他信息,按需转换 print(str) }
乍一看这里可能会有疑惑:我们给 WKWebView 绑定了 WKNavigationDelegate,但是 WKScriptMessageHandler 并没有提供代理方法啊。其实与此相对应的过程出现在上一段代码中的第5行:
config.userContentController.addScriptMessageHandler这一句。
相关文章推荐
- android Mediaplayer各种属性和方法简单介绍
- 创建cocos2d-x工程及文件夹解析
- AndroidStudio 中使用 百度地图 <一> 百度地图的导入和集成,个人摘要
- Android动画
- App推送功能-APNS
- 今天是3月12号。大明宫钻石店忙回来下午做了比比送的这本书的2.1会员登陆页的临摹
- Android开发中,那些让你觉得相见恨晚的方法、类或接口
- Android相关问题记录
- Objective-c 深浅复制
- ImageView的src与background的区别分析
- Android逆向分析基础-ARM 汇编语言基础
- 一个帖子学会Android开发四大组件
- Android Studio入门到精通
- Android 事件监听处理
- Android显示通知栏消息
- Android Studio报错--Error: Library projects cannot set applicationId. applicationI
- android 外部启动activity,自定义action,action常量大全
- 【转】unity3d所要知道的基础知识体系大纲
- Unity面试着重复习重点
- iOS GCD使用