This plugin provides client-side integration for the CodePush service, allowing you to easily add a dynamic update experience to your NativeScript app(s).
BEWARE: Sometime June 2017 it is expected you can no longer create new CodePush apps anymore. Apps created beforehand will continue to work for the foreseeable future though. The exact date? Unknown, but you'll notice when trying to create an app with the CodePush CLI.
UPDATE june 19 2017: The aforementioned change has been made; sadly no new CodePush NativeScript apps can be created. See this issue for details.
📣 📣 📣 UPDATE may 9 2019: we're considering rebooting our efforts. Stay tuned!
A NativeScript app is composed of XML/HTML, CSS and JavaScript files and any accompanying images, which are bundled together by the NativeScript CLI and distributed as part of a platform-specific binary (i.e. an .ipa or .apk file). Once the app is released, updating either the code (e.g. making bug fixes, adding new features) or image assets, requires you to recompile and redistribute the entire binary, which of course, includes any review time associated with the store(s) you are publishing to.
The CodePush plugin helps get product improvements in front of your end users instantly, by keeping your code and images synchronized with updates you release to the CodePush server. This way, your app gets the benefits of an offline mobile experience, as well as the "web-like" agility of side-loading updates as soon as they are available. It's a win-win!
In order to ensure that your end users always have a functioning version of your app, the CodePush plugin maintains a copy of the previous update, so that in the event that you accidentally push an update which includes a crash, it can automatically roll back. This way, you can rest assured that your newfound release agility won't result in users becoming blocked before you have a chance to roll back on the server. It's a win-win-win!
To confuse you even more, have a diagram:
- Anything inside your
/appfolder. - Anything inside your
/node_modulesfolder.
- NativeScript platform updates. Example: bumping
tns-androidfrom version 2.5.1 to 2.5.2. - Plugins updates that also require a different version of a native library it depends on.
So as long as you don't change versions of dependencies and tns platforms in your package.json you can push happily. And if you do bump a version of a dependency make sure there are no changed platform libraries.
TODO test this workflow!
npm i -g nativescript-code-push-cliLog in if you already have an account:
nativescript-code-push loginRegister if you don't have an account yet:
nativescript-code-push registerCreate an app for each OS you target:
nativescript-code-push app add MyApp-IOS ios nativescript nativescript-code-push app add MyApp-Android android nativescriptThis will show you your deployment keys you'll need when connecting to the CodePush server.
nativescript-code-push app lstns plugin add nativescript-code-pushIf you're restricting access to the internet from within your app, make sure you whitelist
https://nativescript-codepush-server.herokuapp.com.
With the CodePush plugin installed and configured, the only thing left is to add the necessary code to your app to control when it checks for updates.
If an update is available, it will be silently downloaded, and installed the next time the app is restarted (so a cold boot, triggered either explicitly by the end user or by the OS), which ensures the least invasive experience for your end users. In the future we may add an option to reload the app instantly or upon resuming.
Also check out the demo for a solid example.
// import the main plugin classes import { CodePush } from "nativescript-code-push"; // and at some point in your app: CodePush.sync({ deploymentKey: "your-deployment-key" });If you have an iOS and Android app, and want some feedback during the sync, you can use this more elaborate version instead:
import { CodePush, InstallMode, SyncStatus } from "nativescript-code-push"; import { isIOS } from "tns-core-modules/platform"; CodePush.sync({ deploymentKey: isIOS ? "your-ios-deployment-key" : "your-android-deployment-key", installMode: InstallMode.ON_NEXT_RESTART, // this is the default, and at this moment the only option serverUrl: "https://your-backend.server" // by default this is our shared cloud hosted backend server }, (syncStatus: SyncStatus): void => { console.log("CodePush syncStatus: " + syncStatus); if (syncStatus === SyncStatus.UP_TO_DATE) { console.log("CodePush: no pending updates; you're running the latest version!"); } else if (syncStatus === SyncStatus.UPDATE_INSTALLED) { console.log("CodePush: update installed - it will be activated upon next cold boot"); } });It's recommended to check for updates more than once in a cold boot cycle, so it may be easiest to tie this check to the resume event:
import * as application from "tns-core-modules/application"; // add this in some central place that's executed once in a lifecycle application.on(application.resumeEvent, () => { CodePush.sync(...); });Once your app has been configured and distributed to your users, and you've made some code and/or asset changes, it's time to instantly release them!
The easiest way to do this is to use the release-nativescript command in our CodePush CLI. Its (most relevant) options are:
| param | alias | default | description |
|---|---|---|---|
| deploymentName | d | Staging | Deploy to either "Staging" or "Production". |
| description | des | Description of the changes made to the app with this release. | |
| targetBinaryVersion | t | Semver expression that specifies the binary app version(s) this release is targeting (e.g. 1.1.0, ~1.2.3). | |
| rollout | r | 100% | Percentage of users this release should be available to. The % sign is optional. |
nativescript-code-push release-nativescript <codepush-ios-appname> ios # deploy to Staging nativescript-code-push release-nativescript <codepush-ios-appname> ios --d Production # deploy to Production (default: Staging) nativescript-code-push release-nativescript <codepush-ios-appname> ios --targetBinaryVersion ~1.0.0 # release to users running any 1.x version (default: the exact version in Info.plist) nativescript-code-push release-nativescript <codepush-ios-appname> ios --rollout 25 --description "My awesome iOS version" # percentage of users this release should be immediately available to (default: 100) nativescript-code-push release-nativescript <codepush-android-appname> android # deploy to Staging nativescript-code-push release-nativescript <codepush-android-appname> android --d Production # deploy to Production (default: Staging) nativescript-code-push release-nativescript <codepush-android-appname> android --targetBinaryVersion ~1.0.0 # release to users running any 1.x version (default: the exact version in AndroidManifest.xml)Make sure to create a release build first, so use the same command that you'd use for app store distribution, just don't send it to the AppStore. You can even webpack bundle and uglify your app, it's all transparent to this plugin.
When releasing updates to CodePush, you do not need to bump your app's version since you aren't modifying the app store version at all. CodePush will automatically generate a "label" for each release you make (e.g.
v3) in order to help identify it within your release history.
Using a command like this will tell you how many apps have the update installed:
nativescript-code-push deployment history <codepush-ios-appname> StagingYou may want to play with CodePush before using it in production (smart move!). Perform these steps once you've pushed an update and added the sync command to your app:
$ tns run <platform>. On an iOS device add the--releaseflag so LiveSync doesn't interfere.- kill and restart the app after the update is installed
Support on-resume reloads. I haven't investigated this possibility yet. If it can be pulled off we'll add an option to the sync command.
