小程序iOS客户端框架——控件事件逻辑框架与控件原生化(上)

小程序自发布以来,为开发者和用户提供了一种轻量级的App。作为一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打开应用。小程序也体现了“用完即走”的理念,用户不用关心是否安装太多应用的问题。 微信客户端为小程序的运行提供了框架支持,如service运行环境、页面缓存机制以及控件原生化支持等,本文将对这些部分实现原理做一一介绍。

1.内容概要

微信小程序采用了传统的移动端H5浏览器作为页面运行环境,但是与传统的B/S结构的WEB应用不同,小程序为用户提供了普通H5页面无法达到、近似原生App的控件体验,同时也向开发者提供了功能丰富的API。本文将从小程序运行运行环境及框架开始,详细介绍iOS微信客户端对小程序控件层的框架支撑:用户的开发代码如何与用户界面交互、API的功能分类和设计,另外会简单介绍小程序的页面缓存机制。

另外,对于某些H5无法实现,或实现性能较差的控件,微信小程序采用了“控件原生化”方式,将客户端实现的原生控件提供给开发者使用,本文将对原生控件的设计和体验优化做详细的介绍。

2.小程序运行环境及框架简介

为了对小程序的运行机制展开讨论,我们将从一个简单的小程序按钮开始,对小程序的事件处理流程作一个简单的了解。

在不同操作系统平台做应用开发时,通常开发工具都会以XML语言来描述应用的界面布局,如iOS采用storyboard文件,安卓使用了layout文件。在小程序中,自定义了wxml文件来描述界面布局。以下是一个简单的界面文件示例,展示一个普通的按钮,并绑定了点击事件:

(图1. 只有一个按钮的小程序界面布局)

一个小程序界面除了必须的wxml来描述界面布局外,还可以提供wxss文件作为样式描述(可选)。另外,还需要编写这个页面对应的js文件,开发者的开发代码逻辑都在这个js文件中完成,在该js中处理用户事件、控制对应的界面的变化等等。下面是对图1的界面逻辑进行处理的js文件示例,脚本响应按钮的点击事件,并输出日志信息:

(图2. js脚本中响应处理按钮事件)

微信客户端通过 WKWebView以及JavaScriptCore提供了小程序的运行环境。WKWebView负责对wxml和wxss进行解析执行,并渲染展示;JavaScriptCore提供了开发者所写的逻辑代码(JavasScript)的运行环境,该运行环境我们称之为Service,Service中的代码与WebView中的代码完全隔离,如图3所示。

(图3. 小程序运行环境框架)

上图中,绿色部分为客户端提供的支持框架,白色部分为前端逻辑。如图所示,一个小程序就对应了一个Service,客户端通过JavaScriptCore为开发者的Service代码提供了运行环境;一个小程序可能有一个或多个Page作为向用户展示内容的交互界面,客户端由WKWebView提供了Page解析和渲染支持;页面与页面之间的通信通过Service环境中转。

用户点击页面中的Button控件后,点击流消息数据在微信客户端的流转时序如图4:

(图4. 小程序按钮点击事件时序图)

当前端Web JS监听到用户的按钮点击行为后,通过WebKit提供的消息传递机制(PostMessage)将点击事件发送给微信客户端当前页面的WKWebView,WKWebView再将该点击事件交由当前小程序的客户端Native Service环境,通过Native JSCore(JavaScriptCore),回调执行到前端Service Js代码中的onClick监听函数。

下面依旧以按钮为例,通过伪代码实现来理解上述过程:

a、开发者在界面wxml中为button绑定监听函数:

b、JSSDK将onClick事件发送到service:

c、service中监听并执行绑定函数:

上述流程中使用到的WeixinJSBridge对象承担了发送和监听事件消息的任务,publish函数负责发送消息到客户端,subsribe负责接收客户端publish的消息。将在下一节做详细的介绍

3. 数据传输框架与WeixinJSBridge

的实现

在普通的H5页面开发模式下,每一个WebView页面是一个相对独立的运行环境,如果页面与页面之间有数据交互的需求,可以选择的通信方式较为单一,如采用cookie、localstorage,甚至通过query参数来进行数据传递。如前所述:一个小程序由多个WebView构成,H5的常规开发结构远远达不到小程序App开发的数据传输需求,也不符合App开发的习惯。

鉴于上述原因,微信客户端为每个小程序提供了独立的运行环境(小程序内部称为Service),该运行环境保持与小程序一致的生命周期,提供了该小程序运行中全部WebView的逻辑支撑能力:

 A.  处理WebView控件上用户交互事件的能力

B. 为开发者提供相对隔离的逻辑开发环境

C. 提供WebView与WebView之间的数据通信能力

D. 监控小程序以及每个页面(WebView)的生命周期,以App事件的方式通知到开发者

上一节通过对按钮点击事件的处理,介绍了A能力的实现;对于B能力,iOS客户端采用了JavaScriptCore库作为小程序用户代码的运行环境,保证了运行环境的隔离;同时JavaScriptCore也提供了小程序能正常运行的核心功能C:即前端JavaScript脚本与客户端之间的数据通信能力的支持,该能力主要通过WeixinJSBridge对象来实现,下面就对WeixinJSBridge的设计做详细介绍。

为了满足小程序的通信需求,WeixinJSBridge需支持如下基本的通信接口:

通过JavaScript调用微信客户端(Objective C)中的函数

微信客户端(Objective C)执行JavaScript脚本的function

为了前端开发方便,WeixinJSBridge提供了同一套代码,同时对Webview和Service进行了能力支持。

WeixinJSBridge.publish

在Webview端,通过webkit提供的postMessage来将网页数据传输到Objective C监听函数,客户端直接透传到小程序service;在Service端调用执行Objective C中的block将数据传输到客户端,客户端再将数据透传到当前Webview。

WeixinJSBridge.subscribe

注册监听函数,监听客户端ObjectiveC代码的函数调用。webview端监听Service中的publish调用;Service端则监听Webview中的publish调用。

WeixinJSBridge.invoke

传输逻辑与publish函数相同,不过该函数用来提供JSAPI的调用,函数调用到Objective C后,微信客户端将执行对应的JSAPI。

WeixinJSBridge.on

监听客户端主动抛出来的系统事件,比如小程序启动事件,页面切换事件,以及小程序切换后台事件。

客户端通过提供WeixinJSBridge对象,开发者就可以通过publish和subscribe实现在Service中通过js代码与小程序的WebView通信;通过invoke调用微信客户端的原生能力;并通过on接口监听微信传递过来的通知事件。

4.页面预加载与缓存机制

在小程序中,为了提高页面运行速度,达到类原生体验,提供了页面预加载机制,开发者提交代码后,开发工具后台编译代码包时,会预生成page-frame.html(包含一些描述页面结构的 JavaScript 代码和所有页面通用样式的 CSS 代码):

1

当小程序任务创建时,创建首页webview后,通过WKWebView提供的loadHTMLString接口,加载page-frame.html,页面特有的逻辑通过evaluateJavaScript执行插入到当前页面;

2

首页加载成功后,小程序会在后台预加载新的WebView,并通过loadHTMLString加载page-frame.html;

3

当需要跳转页面时,取缓存中的预加载页,并执行evaluateJavaScript执行页面特有的逻辑,同时需要补充缓存预加载页,为下一次跳转准备;

这种预加载机制极大减少了小程序页面跳转执行耗时,提高了用户的点击体验。

5.两种类型的API的设计与执行流程

小程序的API分为两类:“组件API”和“开发API”。组件API并不直接暴露给开发者,开发API是直接提供给开发者调用的功能性API。开发者在开发过程中可以见到的API只有开发API;对于组件API,前端SDK会封装成组件提供给开发者使用,所以当开发者的页面中使用到了某个组件,并且这个组件使用到了客户端的某些原生功能,那么这个组件在初始化或运行过程中就会调用组件API。

图5展示的是两类API调用时,从前端调用到进入到微信客户端Objective C代码时,所经过的依赖模块,其中WeixinJSBridge在上一节已经做了详细的介绍,Service SDK和Webview SDK分别是前端对WeixinJSBridge的进一步功能性封装。

(图5. 小程序组件相关模块依赖关系 )

P.S.还有文章的下半部分,下周再跟大家见面哟~

如果文章觉得不错,动动小手分享给小伙伴吧

--------------------------------------------------------------------------

原文作者:腾讯工程师王召伟。

来源:腾讯内部KM论坛。

你也想成为腾讯工程师?

也想年终奖人手一部 Iphone X?

那就快加入腾讯NEXT学位吧!

NEXT学位小程序课程第7期火热招生中!

上腾讯课堂官网搜索Next学位还有大量免费体验课等你哟~

  感兴趣的同学赶紧点击原文了解详情吧~

腾讯NEXT学位

求职干货 | 前辈blog  | 前端课程

原文发布于微信公众号 - 腾讯NEXT学位(NextDegree)

原文发表时间:2018-09-19

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏不二小段

【爬虫军火库】AnyProxy安装使用【Windows】

分析网络请求详情是写爬虫应用的初始步骤,抓包便是一种十分强大的分析手段,尤其是对手机App进行抓包,往往能收获到Web端没有的API接口。抓包的工具多种多样,功...

2.2K60
来自专栏IT笔记

前后端分离之Vue项目构建测试打包发布

写在开始 其实之前对前后端分离研究过一段时间,中间由于项目进度耽搁也就不了了之了,最近项目中部分使用到了Vue,恰逢前端小伙伴们居然说要使用这个东西,也许是前端...

39190
来自专栏区块链

XSS攻击——每周小讲堂

我们从一个很蠢的例子开始。 假设网站上有一个很简单的输入框,如果输入123并提交,就会保存并显示在url上。 比如现在填一段JS代码字符串并提交,就会得到一个包...

21260
来自专栏运维

Ubuntu10.04 sudoers文件损坏又没有root密码修复

Ubuntu10.04 sudoers文件损坏又没有root密码修复 昨天遇到一个案子: 一台GIT服务器是安装的Ubuntu10.04的系统,上面有几个普...

18520
来自专栏云计算教程系列

CentOS 如何配置NTP加入NTP池项目

准确的计时对于几乎所有服务或软件都至关重要。在分布式平台上运行的电子邮件,记录器,事件系统和调度程序,用户身份验证机制和服务都需要准确的时间戳来按时间顺序记录事...

18700
来自专栏地方网络工作室的专栏

打造前端 Deepin Linux 工作环境——安装配置 atom 编辑器

打造前端 Deepin Linux 工作环境——安装配置 atom 编辑器 好,我个人推荐大家使用 atom 编辑器,第一是免费,第二是好看,第三是好用。 安装...

60780
来自专栏用户2442861的专栏

Python安装模块出错解决的办法(pip相关的安装)

然后在cmd进入命令行窗口, 进入ez_setup.py目录,我这里是下载放置在F盘,然后输入命令:python ez_setup.py 系统就会自动下载se...

55130
来自专栏Java3y

纳税服务系统总结

纳税服务系统总结 纳税服务系统是我第一个做得比较大的项目(不同于javaWeb小项目),该项目系统来源于传智Java32期,十天的视频课程(想要视频的同学关注我...

31190
来自专栏小白课代表

软件分享 | 3DS MAX 2016安装教程

3D Studio Max,常简称为3d Max或3dsMAX,是Discreet公司开发的(后被Autodesk公司合并)基于PC系统的三维动画渲染和制作软件...

11320
来自专栏武军超python专栏

2018年8月9号飞机大战项目答辩得到的经验和基本的win终端命令

今天遇到的新单词: adapter n适配器 virtual adj 虚拟的 interface n接口 corporation n公司,法人

12730

扫码关注云+社区

领取腾讯云代金券