Más contenido relacionado La actualidad más candente (20) Similar a HotPush with Ionic 2 and CodePush (20) HotPush with Ionic 2 and CodePush10. Ionic 2
Start a new Ionic Project
ionic start pgdays-workshop --v2 --ts
cd pgdays-workshop
10 / 65
11. Ionic 2
Start a new Ionic Project
ionic start pgdays-workshop --v2 --ts
cd pgdays-workshop
Preview in browser
ionic serve
11 / 65
15. CodePush Setup
Install CLI tools
npm install -g code-push-cli
Create CodePush account
code-push register
Register your app
code-push app add <appName>
15 / 65
16. Configuring Cordova for CodePush
Install CodePush plugin
ionic plugin add cordova-plugin-code-push@latest
16 / 65
17. Configuring Cordova for CodePush
Install CodePush plugin
ionic plugin add cordova-plugin-code-push@latest
Install Typings
npm i typings@0.x -g
typings install
github:Microsoft/cordova-plugin-code-push/typings/codePush.d.ts
--save --ambient
17 / 65
18. Configuring Cordova for CodePush
Add Deployment Key to config.xml
config.xml
<platform name="ios">
<preference name="CodePushDeploymentKey" value="YOUR-IOS-DEPLOYMENT-KEY" />
</platform>
18 / 65
19. Configuring Cordova for CodePush
Add Deployment Key to config.xml
config.xml
<platform name="ios">
<preference name="CodePushDeploymentKey" value="YOUR-IOS-DEPLOYMENT-KEY" />
</platform>
Forget your app or key? no problem
code-push app ls # list your registered apps
code-push deployment ls AppName -k
19 / 65
20. Configuring Cordova for CodePush
Let Cordova talk with CodePush
config.xml
<access origin="*" />
<!-- or -->
<access origin="https://codepush.azurewebsites.net" />
<access origin="https://codepush.blob.core.windows.net" />
20 / 65
21. Configuring Cordova for CodePush
Let Cordova talk with CodePush
config.xml
<access origin="*" />
<!-- or -->
<access origin="https://codepush.azurewebsites.net" />
<access origin="https://codepush.blob.core.windows.net" />
Let CodePush work with CSP
www/index.html
<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 *" />
21 / 65
24. Build Settings Tab
app/pages/page1/page1.html
<ion-navbar *navbar>
<ion-title>Settings</ion-title>
</ion-navbar>
<ion-content padding class="page1">
<ion-row>
<ion-col width-50>
<button (click)="checkForUpdate()">
Check For Update
</button>
</ion-col>
<ion-col width-50>
<button (click)="sync()"
[disabled]="!isUpdateAvailable">
Sync
</button>
</ion-col>
</ion-row>
</ion-content>
24 / 65
26. codePush.checkForUpdates
app/pages/page1/page1.ts
import {Page} from 'ionic-angular';
import {ApplicationRef} from '@angular/core'
declare const codePush: CodePushCordovaPlugin;
export class Page1 {
// ...
isUpdateAvailable:boolean = false;
constructor(private appRef: ApplicationRef) { }
checkForUpdate() {
codePush.checkForUpdate((result) => {
this.isUpdateAvailable = result !== null;
this.appRef.tick();
});
}
}
26 / 65
33. New Feature: Status Field
app/pages/page1/page1.html
<!-- ... -->
<ion-content padding class="page1">
<ion-row>
<ion-col width-20>Status:</ion-col>
<ion-col width-80>{{status}}</ion-col>
</ion-row>
<!-- ... -->
</ion-content>
33 / 65
34. app/pages/page1/page1.ts
export class Page1 {
status: string = '';
isProcessing: boolean = false;
// ..
checkForUpdate() {
this.isProcessing = true;
this.status = 'Checking ... '
codePush.checkForUpdate((result) => {
this.isUpdateAvailable = result !== null;
this.status = result === null ? 'Up to Date' : 'Update Available'
this.isProcessing = false;
this.appRef.tick();
});
}
// ...
}
34 / 65
35. Sync the Update
Build & Release CodePush
ionic build
code-push release-cordova pgdays-demo ios
35 / 65
36. Sync the Update
Build & Release CodePush
ionic build
code-push release-cordova pgdays-demo ios
Sync the app
36 / 65
38. Select a Version
app/pages/page1/page1.html
<!-- ... -->
<ion-list radio-group [(ngModel)]="deployment">
<ion-list-header>
Version
</ion-list-header>
<ion-item>
<ion-label>Staging</ion-label>
<ion-radio value="YOUR-IOS-STAGING-KEY"></ion-radio>
</ion-item>
<ion-item>
<ion-label>Production</ion-label>
<ion-radio value="YOUR-IOS-PRODUCTION-KEY"></ion-radio>
</ion-item>
</ion-list>
<!-- ... -->
38 / 65
39. Pass the Deployment Key
app/pages/page1/page1.html
<!-- ... -->
<button
(click)="checkForUpdate(deployment)"
[disabled]="isInProgress">
Check For Updates
</button>
<button
(click)="sync(deployment)"
[disabled]="!isUpdateAvailable">
Sync
</button>
<!-- ... -->
39 / 65
41. Update checkForUpdate
app/pages/page1/page1.ts
export class Page1 {
// ...
checkForUpdate(key) {
this.isInProgress = true;
this.status = 'Checking for Update';
codePush.checkForUpdate((result) => {
this.isUpdateAvailable = result !== null;
this.isInProgress = false;
this.status = result === null ? 'Application is up-to date' : 'Update Available'
this.appRef.tick();
},
null, // error handler
key); // deployment key is an optional 3rd parameter
}
}
41 / 65
43. Display Current Package
app/pages/page1/page1.html
<ion-list radio-group [(ngModel)]="deployment">
<!-- ... -->
<ion-list>
<ion-list-header>
Installed Package
</ion-list-header>
<ion-item>
App Version: {{currentPackage?.appVersion}}
</ion-item>
<ion-item>
Description: {{currentPackage?.description}}
</ion-item>
<ion-item>
Label: {{currentPackage?.label}}
</ion-item>
</ion-list>
43 / 65
44. app/pages/page1/page1.ts
import {Page, Platform} from 'ionic-angular';
// ...
export class Page1 {
// ...
currentPackage: ILocalPackage;
constructor(private platform: Platform,
private appRef: ApplicationRef) { }
ngOnInit() {
this.platform
.ready()
.then( () => this.getCurrentPackage());
}
getCurrentPackage() {
codePush.getCurrentPackage((result: ILocalPackage) => {
this.currentPackage = result;
this.appRef.tick();
})
}
}
44 / 65
48. Deploy
ionic build
code-push release-cordova pgdays-demo ios
-d Staging
--description 'Deployment Select'
Promote
code-push promote pgdays-demo
Staging Production
--des 'Staging -> Production'
Run the app ...
48 / 65
50. Change the Sync button colour
app/pages/page1/page1.html
<button
(click)="sync(deployment)"
[disabled]="!isUpdateAvailable"
secondary> <!-- ionic will set this to be green -->
Sync
</button>
<!-- ... -->
50 / 65
51. Build and Deploy to Staging
ionic build
code-push release-cordova
pgdays-demo ios
-d Staging
--description 'Color Change'
51 / 65
52. Build and Deploy to Staging
ionic build
code-push release-cordova
pgdays-demo ios
-d Staging
--description 'Color Change'
Run the app ...
Select Production, and Sync
Select Staging, and Sync
52 / 65
55. codePush.sync(
syncCallback?: SuccessCallback<SyncStatus>,
syncOptions?: SyncOptions,
downloadProgress?: SuccessCallback<DownloadProgress>): void;
declare enum SyncStatus {
UP_TO_DATE,
UPDATE_INSTALLED,
UPDATE_IGNORED,
ERROR,
IN_PROGRESS,
CHECKING_FOR_UPDATE,
AWAITING_USER_ACTION,
DOWNLOADING_PACKAGE,
INSTALLING_UPDATE
}
55 / 65
56. app/pages/page1/page1.ts
// ...
export class Page1 {
syncHandler(status: SyncStatus) {
// ...
}
sync(key) {
codePush.sync((status) => this.syncHandler(status),
{
updateDialog: true,
installMode: InstallMode.IMMEDIATE,
deploymentKey: key
});
}
56 / 65
57. syncHandler(status: SyncStatus) {
switch (status) {
case SyncStatus.UP_TO_DATE:
this.status = 'Up-to-date';
break;
case SyncStatus.UPDATE_INSTALLED:
this.status = 'Update Installed';
break;
case SyncStatus.UPDATE_IGNORED:
this.status = 'Update Ignored';
break;
case SyncStatus.ERROR:
this.status = 'Error';
break;
// ...
}
57 / 65
58. syncHandler(status: SyncStatus) {
switch(status) {
// ...
case SyncStatus.IN_PROGRESS:
this.status = 'In Progress';
break;
case SyncStatus.CHECKING_FOR_UPDATE:
this.status = 'Checking for Update';
break;
case SyncStatus.AWAITING_USER_ACTION:
this.status = 'Awaiting User Action';
break;
case SyncStatus.DOWNLOADING_PACKAGE:
this.status = 'Downloading Package';
break;
case SyncStatus.INSTALLING_UPDATE:
this.status = 'Installing Update';
break;
}
this.appRef.tick();
}
// ...
}
58 / 65
62. // ...
export class Page1 {
downloadProgress: DownloadProgress
// ...
updateDownloadProgress(downloadProgress: DownloadProgress) {
this.downloadProgress = downloadProgress;
this.appRef.tick();
}
sync(key) {
codePush.sync((status) => this.syncHandler(status),
{
updateDialog: true,
installMode: InstallMode.IMMEDIATE,
deploymentKey: key
},
(progress) => this.updateDownloadProgress(progress));
}
}
62 / 65
63. <!-- .... after the sync buttons --->
<ion-row>
<ion-col width-25>Progress:</ion-col>
<ion-col width-75>
{{downloadProgress?.receivedBytes}} / {{downloadProgress?.totalBytes}}
</ion-col>
</ion-row>
63 / 65