开发

开发模拟器扩展

要扩展 API 和组件时,了解模拟器的一些实现和提供的功能会对更容易理解下面的内容。
可以参考文档内的示例代码,开发一个模拟器扩展。

一个简单的模拟器扩展目录结构

1
2
3
4
5
6
7
8
9
├── README.md
├── package.json
└── src
├── assets // 静态资源
├── webview.js // webview中注入的主入口文件
├── master.js // master中注入的主入口文件
├── slave.js // slave中注入的主入口文件
└── form.js // 渲染进程的主入口文件

如何添加 extensionjs

当开发新的 native 能力时,需要加载对应的框架代码,在 vendor 目录下,创建 ${host}-program-extension/1.0.0/ 目录,将自己实现的 extension.js 放入即可。

如何实现模拟器扩展功能

开发者需要定义一个 package.json 文件用来描述入口文件位置。模拟器扩展提供了四个入口,其中 form 入口运行在 electron 的渲染进程中,另外三个入口(master、slave、web-view 组件)运行在 electron 的 webview 进程中,开发者可根据需要实现其中的一个或多个入口,每个入口需要导出一个对象,以下为详细说明:

package.json

package.json 声明了各个入口文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"name": "demo-api",
"version": "1.0.0",
"description": "swan demo api",
"main": "./src",
"entry": {
"form": {
"main": "./src/index.js",
"styles": [
"./src/components/login/index.css"
]
},
"master": {
"main": "./src/webview/master/index.js"
},
"slave": {
"main": "./src/webview/slave.js"
},
"webview": {
"main": "./src/webview/master/webview.js"
}
}
}

渲染进程入口 form

1
2
3
4
module.exports = {
onReady(context) {},
onRefresh(context) {}
}

渲染进程入口可以使用二个生命周期:

onReady onRefresh

  • onReady 会在模拟器启动完成时被调用;
  • onRefresh 会在模拟器刷新时被调用;

它们都会提供一个对象 context

webview 进程入口(包括 master、slave、web-view 组件)

1
2
3
4
5
6
7
8
module.exports = {
schemeHandlers: {},
middleWares: [],
syncMiddleWares: [],
async onReady(context) {},
onRefresh(context) {},
onDestroy(context) {}
}

webview 进程入口包含两个生命周期以及一些属性:

onReady

onReady 会在模拟器启动完成时被调用;onReady 提供了 runtimeContext 对象

schemeHandlers

schemeHandlers 用于实现相应的 swan-api 。
schemeHandlers 的函数签名如下:

1
(context: Context) => (schemeInfo: SchemeInfo) => any

其中 Context 和 onReady 中的 context 相同,schemeInfo 包含以下属性:


  • raw - 原始的 scheme 字符串
  • action - scheme 中的 action 名称
  • boxType - scheme 协议头
  • schemeName - scheme 调起来源
  • query - scheme 携带的 query
    • params - query 中的参数
  • ver - scheme 版本信息

middleWares 和 syncMiddleWares

middleWare 和 syncMiddleWares 都用来声明中间件

middleWares 会在异步的 schemeHandlers 中增加中间件,而 syncMiddleWares 会在同步的 schemeHandlers 中增加中间件,通过 action 可以区分一个 scheme 是同步处理还是异步处理,同步处理的 scheme 中 action 一定包含 Sync 。

它们的函数签名为:

1
(context: Context) => (schemeInfo: SchemeInfo) => (next: Handler) => any

其中 Context 和 SchemeInfo 和上文 schemeHandlers 中的相同,Handler 为处理 schemeInfo 的函数。

下面是一个简单的中间件例子,会打印所有异步 schemeHandler 处理前的 scheme 信息:

1
2
3
4
exports.logger = context => next => async scheme => {
console.debug('【scheme before】', scheme.action, scheme);
return next(scheme);
};