【Ionic】Ionic实现iOS与Android端代码『热更新』与Android升级下载功能

热更新的好处

通常ionic源码可包括(HTML,JavaScript,CSS文件和其他资源),往常我们必须通过提交程序到应用市场,经过漫长的审核后才可让用户更新,每改动一个小地方都需要重新打新版本。

现在ionic通过使用cordova插件cordova-hot-code-push实现实现iOS与Android端代码『热更新』功能,可不必发布应用市场经平台审核,便可动态更新App源码的目的

热更新实现原理

基础实现方法

1、安装 cordova-hot-code-push-cli

使用命令安装

     
     
1
     
     
npm install -g cordova-hot-code-push-cli

主要是生成检测配置文件,通常是在 www 目录下动态生成 chcp.json 和 chcp.manifest 生成两个文件,插件源码地址:

https://github.com/nordnet/cordova-hot-code-push

2、创建项目

包含 www 目录的项目,已有项目无需重新创建

3、安装热更新插件

使用命令安装

     
     
1
2
3
     
     
ionic plugin add cordova-hot-code-push-plugin
ionic plugin add cordova-hot-code-push-local-dev-addon

4、打包封装

执行命令cordova-hcp build 或者 cordova build

5、启动 hcp server 服务

重新打开一个终端窗口,cd到项目目录(包含www目录的父级目录)执行命令

     
     
1
     
     
cordova-hcp server

稍等会在 www 目录下动态生成 chcp.json 和 chcp.manifest 生成两个文件

6、正常在运行完成前4步以后会在我们config.xml动态加入如图所示链接地址

图中链接地址https://1980480f.ngrok.io/chcp.json,修改为在第8步www目录里chcp.json文件可访问的地址:

例如:http://kaibin.me/hotcode/chcp.json

7、运行代码或打包我们的App

8、修改我们想要更新的代码

然后修改 chcp.json 文件的 content_url ,此地址为我们项目放置的地址

     
     
1
2
3
4
5
6
     
     
{
"autogenerated": true,
"release": "2016.07.17-11.36.13",
"content_url": "http://kaibin.me/hotcode",
"update": "now"
}

9、将项目www目录代码上传到服务器可访问的目录里

例如在服务器根目录创建hotcode命名的目录将项目www里的文件上传上去

10、 关闭我们的应用重新打开,看看代码是否更新成功

优化流程

1.创建cordova-hcp模板

线上测试可卸载掉 cordova-hot-code-push-local-dev-addon防止每次自动更新新版本,可通过命令卸载:

     
     
1
     
     
cordova plugin remove cordova-hot-code-push-local-dev-addon

可以在 cordova 项目根目录下放一个 cordova-hcp.json,这是个模板文件
这样每次执行

     
     
1
     
     
cordova-hcp build

就会利用这个模板生成新的 chcp.json,而不用手动更改 www/chcp.json了。
cordova-hcp.json内容如下:

     
     
1
2
3
4
5
6
7
     
     
{
"autogenerated": true,
"content_url": "http://kaibin.me/hotcode",
"min_native_interface": 1, // app内核版本号
"ios_identifier": "https://itunes.apple.com/cn/app/***", // iOS上线后的地址,用于内核版本更新后的确认跳转
"update": "now"
}

2.Build options build设置,配置开发环境、测试环境与生产环境

  • 在 /Cordova/Testproject/ 下创建 chcpbuild.options 文件,文件内容如下:
     
     
1
2
3
4
5
6
7
8
9
10
11
     
     
{
"dev": {
"config-file": "https://dev.kaibin.me/hotcode/www/chcp.json"
},
"production": {
"config-file": "https://kaibin.me/hotcode/chcp.json"
},
"QA": {
"config-file": "https://test.kaibin.me/hotcode/chcp.json"
}
}
  • 这样在build app的时候, 转为开发要用的服务器, 可执行:
     
     
1
     
     
ionic build -- chcp-dev

结果就是, 特定拍下的 config.xml 文件(比如, /Cordova/TestProject/platforms/android/res/xml/config.xml) 变成了这样:

     
     
1
2
3
     
     
<chcp>
<config-file url="https://dev.kaibin.me/hotcode/chcp.json"/>
</chcp>
  • 当我们需要上架app的时候 (Google Play, App Store) - 我们正常build:
     
     
1
     
     
ionic build --release

这样 config.xml 不会改变

如果没有使用 chcpbuild.options 插件会使用 config.xml 里面默认的值。

文件必须位于 Cordova 项目根目录. 在这个文件里面,指定(JSON格式) 所有想改变 config.xml 文件的配置,源文件 config.xml (Cordova项目根目录) 不会发生变动, 改变的是 特定平台下的 config.xml (在cordova build过程的 after_prepare 阶段)。

通过min_native_interface监控app是否提示更新

所需最小的外壳app版本. 这是app的build版本号,是个整型数字, 不是应用商店中看到的形如”1.0.0”字符串。

在 config.xml中,这样指定build版本号:

     
     
1
2
3
4
     
     
<chcp>
<native-interface version="1"/>
<config-file url="http://kaibin.me/hotcode/chcp.json"/>
</chcp>

与www目录下的chcp.json里面的min_native_interface数值相对应

例如:app外壳里的config.xml是这样的:

     
     
1
2
3
4
     
     
<chcp>
<native-interface version="1"/>
<config-file url="http://kaibin.me/hotcode/chcp.json"/>
</chcp>

若服务器里的min_native_interface也对应是1,不会出现提示用户升级的状态,正常修改www目录的内容通过更新release值,可实现热更新。

     
     
1
2
3
4
5
6
7
8
     
     
{
"autogenerated": true,
"content_url": "http://kaibin.me/hotcode",
"min_native_interface": 1, // app内核版本号
"ios_identifier": "https://itunes.apple.com/cn/app/***", // iOS上线后的地址,用于内核版本更新后的确认跳转
"release": "2017.07.17-12.22.11",
"update": "now"
}

假设你的外壳app加了个新的插件,应该会更新外壳app。为了防止用户通过热更新下载了不适合他现有外壳app的web内容,你应该设置 min_native_interface 这个值

     
     
1
2
3
4
5
6
7
8
9
     
     
{
"autogenerated": true,
"content_url": "http://kaibin.me/hotcode",
"min_native_interface": 1, // app内核版本号
"ios_identifier": "https://itunes.apple.com/cn/app/***", // iOS上线后的地址,用于内核版本更新后的确认跳转
"release": "2017.07.17-12.28.21",
"min_native_interface": 2
"update": "now"
}

插件加载到这段json的时候, 发现 min_native_interface 比当前外壳app的build号要大,便不会下载web内容。而是触发一个chcp_updateLoadFailed 错误通知, 告诉用户需要升级外壳app了。

chcp.json中update字段含义

指定了什么时候安装web内容更新,支持的值有:

start - app启动时安装更新,默认值
resume - app从后台切换过来的时候安装更新
now - web内容下载完毕即安装更新

引导用户去应用商店更新外壳app或下载新版本

通过给web更新设置最小支持的外壳app版本 min_native_interface。 如果插件检查发现用户安装的外壳app版本比服务端新的web内容要求的版本要低,就会触发错误事件,错误码:

     
     
1
     
     
chcp.error.APPLICATION_BUILD_VERSION_TOO_LOW

通过这个错误码可通过弹窗提示用户去升级,跳转到AppStore或下载新安装包(国内因GFW,跳转到google应用商店就算了= =)

     
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
     
     
var appUpdate = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind any events that are required.
// Usually you should subscribe on 'deviceready' event to know, when you can start calling cordova modules
bindEvents: function() {
document.addEventListener( 'deviceready', this.onDeviceReady, false);
document.addEventListener( 'chcp_updateLoadFailed', this.onUpdateLoadError, false);
},
// deviceready Event Handler
onDeviceReady: function() {
},
onUpdateLoadError: function(eventData) {
var error = eventData.detail.error;
// 当检测出内核版本过小
if (error && error.code == chcp.error.APPLICATION_BUILD_VERSION_TOO_LOW) {
var dialogMessage = '有新的版本,请下载更新';
// iOS端 直接弹窗提示升级,点击ok后自动跳转
if(ionic.Platform.isIOS()){
chcp.requestApplicationUpdate(dialogMessage, this.userWentToStoreCallback, this.userDeclinedRedirectCallback);
// Android端 提示升级下载最新APK文件
} else if(ionic.Platform.isAndroid()){
var confirmPopup = $ionicPopup.confirm({
template: '有新的版本,请下载更新',
cssClass: 'popup',
cancelText: '取消',
okText: '升级'
});
confirmPopup.then( function (res) {
if (res) {
$ionicLoading.show({
template: "已经下载:0%"
});
window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory, function(fileEntry) {
fileEntry.getDirectory( "***(app名称)", { create: true, exclusive: false }, function (fileEntry) {
//下载代码
var fileTransfer = new FileTransfer();
fileTransfer.download( "app下载地址", fileEntry.toInternalURL()+ "***(app名称).apk", function(entry) {
// 打开下载下来的APP
cordova.plugins.fileOpener2.open(
entry.toInternalURL(), //下载文件保存地址
'application/vnd.android.package-archive', { //以APK文件方式打开
error: function(err) {
},
success: function() {}
});
}, function(err) {
}, true);
fileTransfer.onprogress = function(progressEvent) {
$timeout( function () {
var downloadProgress = (progressEvent.loaded / progressEvent.total) * 100;
$ionicLoading.show({
template: "已经下载:" + Math.floor(downloadProgress) + "%"
});
if (downloadProgress > 99) {
$ionicLoading.hide();
}
});
};
}, function(err){alert( "创建失败")});
});
}
});
}
}
},
userWentToStoreCallback: function() {
// user went to the store from the dialog
},
userDeclinedRedirectCallback: function() {
// User didn't want to leave the app.
// Maybe he will update later.
}
};
appUpdate.initialize();

iOS与Android的出现的问题

在build ios的app时config.xml

     
     
1
     
     
<name>*** </name>

name不可使用中文,设置app名称为中文,可通过Xcode修改Resources目录下的***-Info.plist内的Bundle display name字段即可。

这篇文章写得很详细,特转载过来慢慢研究,十分感谢本文作者贡献出如此好得文章。转载地址:http://kaibin.me/2016/07/17/ionic-hotcode/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值