Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
C
CodePush-iOS
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge Requests 0
    • Merge Requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Analytics
    • Analytics
    • CI/CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Demo
  • CodePush-iOS
  • Wiki
  • codepush研究记录

Last edited by John Huang Oct 24, 2019
Page history

codepush研究记录

概述

本文档记录了CodePush的研究过程。主要记录了过程当中的尝试、步骤、代码、错误等等内容。 本记录主旨在于1. 备忘。2. 避免重复研究。3. 反复在错误方向上是错。 记录内容按时间先后记录,未经分类整理,相对混乱。

研究记录

在研究Cordova热更新的时候发现微软的AppCenter已经提供了一套完整的热更新方案。其中也包含了关于Cordova的热更新策略,不用自己开发。 这套策略大概叫做「CodePush」(后文简称「CP」)

本文为将记录研究和实践「CP」的步骤、问题、方法以及备忘。


创建项目以测试方案。 创建一个Cordova项目测试、实践「CP」方案。 需要注意的是,iOS和Android要独立建立项目,这说的是App的项目要独立(Web可以共用),否则会出现冲突的情况。 因为对iOS比较熟悉,这里先建立一个iOS的「CP」项目。 项目名:CodePush-iOS 简单用Cordova create创建项目,没有对项目的配置,包括项目名进行任何修改。

$ cordova create CodePush-iOS

创建以后添加iOS平台。 用xcode打开项目,经过测试能够正常运行。

$ cordova platform add ios

我把项目commit到gitlab上,方便后面进行不同的分支测试。


补充一些学习材料 https://github.com/microsoft/cordova-plugin-code-push#getting-started

https://github.com/microsoft/code-push/blob/master/cli/README.md#releasing-updates


添加CodePushPlugin

$ cordova plugin add cordova-plugin-code-push@latest

需要在config.xml添加下面配置。 Android

<platform name="android">
    <preference name="CodePushDeploymentKey" value="YOUR-ANDROID-DEPLOYMENT-KEY" />
</platform>

iOS:

<platform name="ios">
    <preference name="CodePushDeploymentKey" value="YOUR-IOS-DEPLOYMENT-KEY" />
</platform>

YOUR-XXX-DEPLOYMENT-KEY需要通过向AppCenter注册App获取,后面再修改


[CP]提供一套管理工具,CLI。 安装管理工具:

$ npm install -g code-push-cli

安装完CLI以后可以通过code-push命令进行[CP]相关的管理操作。


注册AppCenter账号

$ code-push register

该命令会在浏览器打开注册网页,注册完以后会返回一个token。把token输入到命令终端完成登录。

注册AppCenter需要微软账号或者也可以通过GitHub,facebook,google账号进行注册。因为主要跟开发有关,跟微软的产品关系不大,我用的GitHub账号进行注册。 注册时大概是这样的: 9145376A-FC2A-4738-BD21-CBA6361FCFA0

如果已经注册过,需要在其它机器上进行登录操作,可以用下面命令进行操作,同样会打开网页进行登录

$ code-push login

向AppCenter账号添加App

$ code-push app add CodePush-iOS ios cordova

code-push app add 是添加命令 CodePush-iOS 项目名 ios cordova 项目平台 添加成功以后终端会显示出App的deployment keys。

日后也可以通过命令查看App的keys。

$ code-push deployment list CodePush-iOS -k

B93F15E1-A1ED-4BD5-AF7B-C72D82FBCFF1

这个key需要填入到前面的config.xml中。

iOS:

<platform name="ios">
    <preference name="CodePushDeploymentKey" value="PIfa8aEs6IMrTBpRxrV61CfqCb895da83381-9533-42a3-bf08-f7d84dac3918" />
</platform>

在AppCenter上也会看到创建的App 09BD6F3A-2CBE-4A73-AD3A-A8267784A878


用命令列出AppCenter上注册的App

$ code-push app ls

7779E9D4-878F-482B-B7D2-C00B1814CEB8

在web的js代码中添加codePush.sync()触发热更新。我在index.js的deviceready事件中添加。

    onDeviceReady: function() {
        this.receivedEvent('deviceready');
        console.log('=========【codePush.sync()】');  //打印一下确认被调用
        codePush.sync();  //添加这段代码触发热更新
    }

需要在index.html文件的

下添加下面元素。没有深入考究具体作用,应该是为了让App能够访问更新的存储网站
  <meta http-equiv="Content-Security-Policy" content="default-src https://codepush.azurewebsites.net 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *" /> 

找到一份关于[CP]操作的视频资料(英文) https://www.youtube.com/watch?v=znHwW6A1Joc&t=308s


在cordova项目的根目录下创建build.json文件,配置iOS项目:

{
  "ios": {
    "debug": {
      "codeSignIdentity": "iPhone Developer",
      "automaticProvisioning": true,
      "developmentTeam": "2WT78RG4ZP",
      "packageType": "development"
    }
  }
}

修改config.xml文件,设置项目名和widget id。 widget id相当于iOS 项目的bundle id。

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.easternphoenix.CodePush-iOS" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>CodePush</name>
    <description>
...
</widget>

修改项目名以后,由于项目名都变更,iOS项目并不会动态刷新,需要把iOS平台删除,然后再重建。

$ cordova platform rm ios
$ cordova platform add ios

build ios项目

$ cordova build ios

在真机上run项目

$ cordova run ios

测试通过,正常运行App。


下面我会修改web的代码,然后尝试推到真机上。

把index.html进行修改,在

上添加了「Haha」
<h1>Apache Cordova Haha</h1>

在项目的platform下用xcode打开ios项目。 在模拟器上运行了一遍,观测到代码在UI上已经生效。 用模拟器运行所以真机的App不受影响。后面尝试通过[CP]推到真机上。


通过safari查看模拟器的运行,发现报错了,错误信息

[Error] Failed to load resource: The requested URL was not found on this server. (acquisition-sdk.js.map, line 0)

真机也出现了同样的情况


删除平台和plugin然后重新安装看情况怎样。 问题没有解决。


按照上面视频材料的步骤操作一次,看看情况。 下面备注尽量简短。


$ cordova create ConnectDemo
$ cd ConnectDemo

$ code-push app add ConnectDemo android cordova

279CE433-6D20-4C0C-ADAD-BA67BA11D0A8


$ cordova plugin add cordova-plugin-code-push

config.xml

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.easternphoenix.ConnectDemo" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>ConnectDemo</name>
    ...
    <platform name="android">
        <allow-intent href="market:*" />
        <preference name="CodePushDeploymentKey" value="jSAP6PyZUBfrwJhfK3to5d5k03AF5da83381-9533-42a3-bf08-f7d84dac3918" />
    </platform>
    ...

index.html

<html>
    <head>
        ...
        <meta http-equiv="Content-Security-Policy" content="default-src https://codepush.appcenter.ms 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
        ...
    </head>
    ...
</html>

index.js


var app = {
    ...
    onDeviceReady: function() {
        this.receivedEvent('deviceready');
        codePush.sync();
    },
    ...
};

app.initialize();

$ cordova platform add android
$ cordova run android

运行成功


在Chrome的地址栏输入:chrome://inspect 然后选择我们的App(Hello World) App在后台成功打印出[CodePush] App is up to date. 并没有发生iOS的情况


回忆: 在配置运行android项目的时候,也出现过CodePush报错,信息大概是CodePush插件与platform不兼容。为了处理报错,反复的删除插件和platform。其中也更新了平台:

$ cordova platform update android
$ cordova platform update ios

继续尝试用CodePush更新代码到App上:

index.html:

<html>
    ...
    <body>
        <div class="app">
            <h1>Apache Cordova Haha</h1>
            ...  
        </div>
        ...
    </body>
</html>

刷新代码

$ cordova prepare

推送更新

$ code-push release ConnectDemo ./platforms/android/app/src/main/assets/www 0.0.1

系统显示推送成功。

在chrome的console用location.reload()方法刷新页面,但App的UI并没有刷新


找到没有刷新的原因,是因为版本配置有问题,config.xml的version是1.0.0,而前面推的是0.0.1。需要对App的版本进行修正。

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.easternphoenix.ConnectDemo" version="1.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    ...
</widget>

推版本

$ code-push release ConnectDemo ./platforms/android/app/src/main/assets/www 1.0.1

在chrome再次刷新,检查到更新,但没有进行加载,信息如下:

codePushUtil.js:36 [CodePush] Checking for update. codePushUtil.js:36 [CodePush] An update is available, but it is targeting a newer binary version than you are currently running. codePushUtil.js:36 [CodePush] App is up to date.


重新配置尝试不同的版本号搭配: config.xml 2.0.0 run 查到更新,并刷新UI

推2.0.1 没刷新UI


列出release历史

$ code-push deployment history ConnectDemo Staging

输出: 9431ABAC-54D3-40A1-A972-F1D7371B5275


需要看看App到底装的哪个版本 查到2.0.0

code-push release命令的版本号是控制哪些个版本需要更新的。 标记2.0.1的release是不能更新到2.0.0的设备上的。 所以策略应该是,让设备安装2.0.0版本,然后推2.0.0版的更新(更新到2.0.1)。


config.xml 3.0.0 run UI刷新到3.0.0

config.xml 3.0.1 推送3.0.0

chrome刷新web 成功检测到更新并且下载安装。关闭重启App后成功更新到新的UI

至此算测试成功(散花)


后续任务:

  • 了解更新的策略和规律
  • 解决研究ios的问题
  • 设计建立应用CodePush的项目设计管理策略
  • 还需要解决android设备的remote debug无法正常运作的问题。(模拟器实在太慢)

CodePush简介: 在SmartSolution开展之初本打算自己实施一套热更新策略。在研究良久以后才偶然发现CodePush已经提供了完整的解决方案。 CodePush原本是一套解决Cordova的热更新方案,早期还需要用户自己建立代码服务器。 发展到后来由微软提供一整套完整方案并融入到它的AppCenter平台中。AppCenter还提供了React-Native的热更新方案。除了热更新以外,还提供了App的分析工具。


回到iso项目上

remove ios platform 和 plugin,更新platform

$ cordova platform rm ios
$ cordova plugin rm ...
$ cordova platform update ios

添加platform,plugin

$ cordova platform add ios
$ cordova plugin add cordova-plugin-code-push

版本号改成0.0.1 config.xml

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.easternphoenix.CodePush-iOS" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    ...
    <platform name="ios">
        <!-- Staging -->
        <preference name="CodePushDeploymentKey" value="PIfa8aEs6IMrTBpRxrV61CfqCb895da83381-9533-42a3-bf08-f7d84dac3918" />
    ...
    </platform>
</widget>

在配置index.html的时候发现meta http-equiv元素下的content值没有配https://codepush.appcenter.ms 修正后:

<meta http-equiv="Content-Security-Policy" content="default-src https://codepush.appcenter.ms 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">

将App从设备删除,重新运行

$ cordova run ios

在safari中debug,仍然提示

[Error] Failed to load resource: The requested URL was not found on this server. (acquisition-sdk.js.map, line 0)

解决策略: 粗略研究后,没有发现有什么具体的发现。 决定另立项目重新测试。在干净的环境下重新测试。步骤上采用android项目中的方法。 先建立一个可行的案例


cordova用指定ios模拟器运行

$ cordova emulate ios --target iPhone-XR

还是报同样的错误


$ cordova emulate ios --target iPhone-XR --debug

同样失败


经查找,App包中确实是缺失了文件

file:///Users/jerry/Library/Developer/CoreSimulator/Devices/77FAA198-2BE7-4608-899A-3DA630F62994/data/Containers/Bundle/Application/32F5C100-4F50-4DF2-9DCD-3C46D82481FB/My%20App.app/www/plugins/code-push/script/acquisition-sdk.js.map

.js.map文件并不会拷贝到项目中


经研究,.js.map文件是javascript的代码转换的信息文件。帮助调试用。 缺失并不妨碍项目的正常运行。

Safari调试中没有打印CodePush的信息是因为console中点选了Errors选项,只显示App的错误信息,CodePush事实上在正常运作。 47E5FD97-74BC-40B2-A53C-00F88D52BB8F 取消选项后console正常显示。


$ code-push release-cordova MyApp ios --targetBinaryVersion "~0.0.0"

刷新成功


这份CodePush的CLI文档比较重要 CodePush Management CLI


这份关于版本控制的信息比较重要 4FC46FD0-6912-46BF-AAE9-6A901CB729F5


经过研究,一般情况下,用"<="的版本号进行更新控制是比较方便的。 譬如最后一次发布的版本号是0.0.2,则用下面命令进行更新是比较合适的:

$ code-push release-cordova MyApp ios --targetBinaryVersion "<=0.0.2"

CodePush的更新操作还是比较繁琐的,一步出错很容易会出现严重的版本错乱问题,最好开发一个脚本或者web应用处理发布版本的事务。


Clone repository
  • code push概念及常用命令
  • codepush研究记录
  • Home