前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >技术 | Hybrid载体的变化(一)

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

作者头像
icepy
发布2019-06-24 17:36:24
8660
发布2019-06-24 17:36:24
举报
文章被收录于专栏:子曰五溪

时至今日,我都在想“微信小程序”为什么不能做成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而已。

代码语言:javascript
复制
self.wkWebView?.loadHTMLString(html, baseURL: URL(string: "https://github.com/icepy"))

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

代码语言:javascript
复制
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获得。

代码语言:javascript
复制
let config = WKWebViewConfiguration();
config.userContentController.add(self, name: "icepyApp");
self.wkWebView = WKWebView(frame: self.view.frame, configuration: config)

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

代码语言:javascript
复制
function sendMessage (){  
    window.webkit.messageHandlers.WinexApp.postMessage.apply(window,arguments);
}

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

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

代码语言:javascript
复制
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,来定位具体的问题。

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

代码语言:javascript
复制
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
}

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

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

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


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-04-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 子曰五溪 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档