专栏首页子曰五溪技术 | Hybrid载体的变化(一)

技术 | Hybrid载体的变化(一)

时至今日,我都在想“微信小程序”为什么不能做成Web式,而是要去加那么一层隔离,终归其原因,还是随着时间向前走,Hybrid的载体也发生了变化,不然该卡的还是一样卡的一逼。从iOS的角度上来说载体从UIWebView变成了WKWebView,Android有着他们自研的X5当然原生的内核,如果你用着Android7.0也不见得会卡,这才是小程序能出来的根本原因,没有载体,一切都是空谈。

今天,我们谈一谈iOS的载体“WKWebView”,有兴趣的朋友可以直接阅读:https://developer.apple.com/reference/webkit/wkwebview ,当然你也可以接着往下看,我对于他的理解,苹果在iOS8中推出的新框架“Webkit”,其中WKWebView就是用来替换原来的UIWebView,一句话,你用它原来UIWebView出现的各种问题都被解决了。当然随之而来的会有一些小问题,比如:WKWebView是一个独立进程,那么它的请求就无法通过系统的URL SYSTEM了,你无法像UIWebView一样,可以通过NSURLProtocol来拦截所有的请求。

如下都简称WK

正常情况下,我们做Hybrid容器基本会用到WKWebView几乎全部的特性,但是也有三个其中重中之重的地方,那就是JavaScript的交互与网页应用的性能监控。至于你想到的如何加载网页,其实很简单,一个load而已。

self.wkWebView?.loadHTMLString(html, baseURL: URL(string: "https://github.com/icepy"))

说到JavaScript交互比较重要的地方是需要实现“WKScriptMessageHandler”协议的“userContentController”方法,这是从JavaScript向Native发送消息的主要渠道,当然如果你用协议的方式也不是不行,至少这个协议的实现它帮你完成了JavaScript到Native类型的转换,比如JavaScript的对象可以转为Dictionary对应的其他类型也是如此。

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {  
    // js 调 App方法传消息过来  
    let body:Dictionary = message.body as! Dictionary<String,String>    print(body)  
    let vdom = ["key":"name"];  
    do {      
        let data:Data = try JSONSerialization.data(withJSONObject: vdom, options: JSONSerialization.WritingOptions.prettyPrinted)      
        let jsonString:String = String(data: data, encoding: .utf8)!
print("\(jsonString)")      
        self.wkWebView?.evaluateJavaScript("receiveNativeEvent(\(jsonString))", completionHandler: { (data, error) in
});
} catch {      
        print("JSON Serialization Error")
}
}

那么JavaScript该如何调用发消息过来呢?在初始化WKWebView时你还需要配置一个Conf,这个Conf中你可以添加一个属性,这个属性在JavaScript这一边你可以通过window.webkit.messageHandlers.icepyApp获得。

let config = WKWebViewConfiguration();
config.userContentController.add(self, name: "icepyApp");
self.wkWebView = WKWebView(frame: self.view.frame, configuration: config)

最终当你需要向Native发送消息时就需要使用这个属性并调用其postMessage方法,比如:

function sendMessage (){  
    window.webkit.messageHandlers.WinexApp.postMessage.apply(window,arguments);
}

Native向JavaScript发送消息就更不用说了,直接调用“evaluateJavaScript”方法注入就好,唯一的优势是在于,发送的消息可以先转成JSON,然后字符串化当参数传入到一个函数里,而你的函数真实接收到的是一个对象,而不是字符串,这就是WKWebView辅助我们做了很多这样的类型转换的事情,如果是UIWebView就没有这么方便的办法了。

说完JavaScript与Native的交互,我还想谈一个非常重要的事情:关于监控,这是一个Hybrid应用的重中之重,只有良好全面的监控,你才能知道应用的运行状态,才能及时的做出判断,来优化应用,更好的服务用户。我们知道WKWebView是一个独立的进程,它的请求都不经过系统的URL SYSTEM,我们很难拦截它,该怎么办?在此之前,我们应该先监控好一个应用打开的完整状态,你需要实现WKNavigationDelegate协议,如下几个方法:

func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {     
    // 页面开始加载时调用
}
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {     
    // 当内容开始返回时调用
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {    
    // 页面加载完成
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {    
    // 页面加载错误    
    print(error)
}

每一个delegate实现中你都应该去做一条日志的记录或者是页面加载完成时间,说到页面加载完成时间肯定是从didStart开始经过didCommit最后didFinish的累加,这个时间不是渲染时间,渲染时间在客户端上是很难统计的,我的建议是做一个JS-API,让Web应用主动的提供渲染完成时间,客户端这边从页面加载完成开始计时,选择一个你认为比较合理的渲染时间,当Web报时大于它时,肯定渲染就不符合预期,这个时候,你还需要从另外的角度去分析问题了,我的建议是使用performance再加上DOM Ready ,全局Error,来定位具体的问题。

对于页面的跳转是否运行,你也可以进行监控,当然在这里只需要实现另外三个协议,比如:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
}

在请求发起之前来决定是否跳转,而这里也是可以写上一条日志的。

关于监控是一个非常复杂的学科,要融合方方面面根据你业务特点的卡位,日久积累下来的经验,肯定有用武之地的。

你身边如果有朋友对混合领域(跨技术栈)或全栈,编程感悟感兴趣,可以转发给他们看哦,^_^先谢过啦。


本文分享自微信公众号 - 子曰五溪(fed-talk)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-04-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 聊个程序员的话题

    最近看几个微信群的气氛很不对,大家也不要气馁,我们聊个程序员的话题,这是我对程序员的认识,希望对找工作的朋友或即将从事这一行的朋友,有所启发。

    icepy
  • 早读《Const Assertions in Literal Expressions in TypeScript》

    https://mariusschulz.com/blog/const-assertions-in-literal-expressions-in-typescr...

    icepy
  • 《深入理解ES6》阅读笔记 --- 块级作用域

    欢迎大家关注我的知乎专栏-《象尘说》,https://zhuanlan.zhihu.com/fed-talk ,微信写技术文章太不好编辑了,So,首发都会在知乎...

    icepy
  • Flutter 与 iOS 原生 WebView 对比

    原文作者:享物说 https://juejin.im/post/5c778d86e51d4506304ee348

    iOSSir
  • WKWebView 那些坑

    WKWebView 是苹果在 WWDC 2014上推出的新一代 webView 组件,用以替代 UIKit 中笨重难用,本文主要讲述适配 WKWebView 过...

    QQ空间开发团队
  • WKWebView 那些坑

    导语 WKWebView 是苹果在 WWDC 2014 上推出的新一代 webView 组件,用以替代 UIKit 中笨重难用、内存泄漏的 UIWebView。...

    腾讯Bugly
  • JVM(三)对象的生死判定和算法详解

    导读:对象除了生死之外,还有其他状态吗?对象真正的死亡,难道只经历一次简单的判定?如何在垂死的边缘“拯救”一个将死对象?判断对象的生死存活都有那些算法?本文带你...

    Java中文社群_老王
  • 海量交易订单查询没做“重试”,一哥们“喜提”P3故障!

    由于现在PDD模式比较火,某大厂的一哥们,接到老板的需求,做一个拼团业务,具体的业务需求是这样的:

    JAVA葵花宝典
  • 快速学习-Linux文档的查看指令

    作用:查看一个文件的末n行 语法:#tail -n 文件的路径 说明:-n可以不写,不写,默认表示10行。 案例:使用tail指令查看root/insta...

    cwl_java
  • 一看就会又超级实用的Excel10大技巧

    本期责编:Sophie 普通人需要用到的Excel的功能不到其全部功能的10%。也就是说,对于绝大部分的用户来说,只要掌握了几个必须懂的Excel表格的基本操作...

    CDA数据分析师

扫码关注云+社区

领取腾讯云代金券