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
This is an old version of this page. You can view the most recent version or browse the 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账号进行注册。 注册时大概是这样的: b663c7b1ccfbf6ce36f89d010b91cc0a.png

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

$ 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

1b9f50b00c01f910bbf48767919c2184.png

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

iOS:

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

在AppCenter上也会看到创建的App f9ded211b543413783e974a5a560a52e.png


用命令列出AppCenter上注册的App

$ code-push app ls

22d06b0ae7ec94111f0671a3583e6e4f.png


在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

d45ecf504eb095ae3463b3bcee1d28f1.png


$ 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

输出: 83bea552936464348fb6533bab565883.png


需要看看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事实上在正常运作。 b78c89442ae179480ff49bd60c9c1eaa.png 取消选项后console正常显示。


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

刷新成功


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


这份关于版本控制的信息比较重要 60463226e8facf85b18f39a7f9c0a688.png


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

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

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


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