mirror of
https://github.com/zhigang1992/react-native-code-push.git
synced 2026-05-19 19:39:54 +08:00
Merge pull request #64 from Microsoft/restart_fix
Updating restartApp and setDeploymentKey
This commit is contained in:
@@ -6,13 +6,21 @@ var packageMixins = require("./package-mixins")(NativeCodePush);
|
||||
var requestFetchAdapter = require("./request-fetch-adapter.js");
|
||||
var Sdk = require("code-push/script/acquisition-sdk").AcquisitionManager;
|
||||
|
||||
function checkForUpdate() {
|
||||
function checkForUpdate(deploymentKey = null) {
|
||||
var config;
|
||||
var sdk;
|
||||
|
||||
return getConfiguration()
|
||||
.then((configResult) => {
|
||||
config = configResult;
|
||||
|
||||
// If a deployment key was explicitly provided,
|
||||
// then let's override the one we retrieved
|
||||
// from the native-side of the app.
|
||||
if (deploymentKey) {
|
||||
config.deploymentKey = deploymentKey;
|
||||
}
|
||||
|
||||
return getSdk();
|
||||
})
|
||||
.then((sdkResult) => {
|
||||
@@ -51,12 +59,10 @@ function checkForUpdate() {
|
||||
});
|
||||
}
|
||||
|
||||
var isConfigValid = true;
|
||||
|
||||
var getConfiguration = (() => {
|
||||
var config;
|
||||
return function getConfiguration() {
|
||||
if (config && isConfigValid) {
|
||||
if (config) {
|
||||
return Promise.resolve(config);
|
||||
} else if (testConfig) {
|
||||
return Promise.resolve(testConfig);
|
||||
@@ -64,7 +70,6 @@ var getConfiguration = (() => {
|
||||
return NativeCodePush.getConfiguration()
|
||||
.then((configuration) => {
|
||||
if (!config) config = configuration;
|
||||
isConfigValid = true;
|
||||
return config;
|
||||
});
|
||||
}
|
||||
@@ -114,20 +119,6 @@ function log(message) {
|
||||
console.log(`[CodePush] ${message}`)
|
||||
}
|
||||
|
||||
function restartApp(rollbackTimeout = 0) {
|
||||
NativeCodePush.restartApp(rollbackTimeout);
|
||||
}
|
||||
|
||||
function setDeploymentKey(deploymentKey) {
|
||||
return NativeCodePush.setDeploymentKey(deploymentKey)
|
||||
.then(() => {
|
||||
// Mark the local copy of the config data
|
||||
// as invalid since we just modified it
|
||||
// on the native end.
|
||||
isConfigValid = false;
|
||||
});
|
||||
}
|
||||
|
||||
var testConfig;
|
||||
var testSdk;
|
||||
|
||||
@@ -150,6 +141,7 @@ function setUpTestDependencies(providedTestSdk, providedTestConfig, testNativeBr
|
||||
function sync(options = {}, syncStatusChangeCallback, downloadProgressCallback) {
|
||||
var syncOptions = {
|
||||
|
||||
deploymentKey: null,
|
||||
ignoreFailedUpdates: true,
|
||||
installMode: CodePush.InstallMode.ON_NEXT_RESTART,
|
||||
rollbackTimeout: 0,
|
||||
@@ -205,7 +197,7 @@ function sync(options = {}, syncStatusChangeCallback, downloadProgressCallback)
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
syncStatusChangeCallback(CodePush.SyncStatus.CHECKING_FOR_UPDATE);
|
||||
checkForUpdate()
|
||||
checkForUpdate(syncOptions.deploymentKey)
|
||||
.then((remotePackage) => {
|
||||
var doDownloadAndInstall = () => {
|
||||
syncStatusChangeCallback(CodePush.SyncStatus.DOWNLOADING_PACKAGE);
|
||||
@@ -288,8 +280,7 @@ var CodePush = {
|
||||
getCurrentPackage: getCurrentPackage,
|
||||
log: log,
|
||||
notifyApplicationReady: NativeCodePush.notifyApplicationReady,
|
||||
restartApp: restartApp,
|
||||
setDeploymentKey: setDeploymentKey,
|
||||
restartPendingUpdate: NativeCodePush.restartPendingUpdate,
|
||||
setUpTestDependencies: setUpTestDependencies,
|
||||
sync: sync,
|
||||
InstallMode: {
|
||||
|
||||
37
CodePush.m
37
CodePush.m
@@ -116,7 +116,8 @@ static NSString * const PendingUpdateRollbackTimeoutKey = @"rollbackTimeout";
|
||||
{
|
||||
// Export the values of the CodePushInstallMode enum
|
||||
// so that the script-side can easily stay in sync
|
||||
return @{ @"codePushInstallModeOnNextRestart":@(CodePushInstallModeOnNextRestart),
|
||||
return @{
|
||||
@"codePushInstallModeOnNextRestart":@(CodePushInstallModeOnNextRestart),
|
||||
@"codePushInstallModeImmediate": @(CodePushInstallModeImmediate),
|
||||
@"codePushInstallModeOnNextResume": @(CodePushInstallModeOnNextResume)
|
||||
};
|
||||
@@ -243,8 +244,8 @@ static NSString * const PendingUpdateRollbackTimeoutKey = @"rollbackTimeout";
|
||||
|
||||
// JavaScript-exported module methods
|
||||
RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
[CodePushPackage downloadPackage:updatePackage
|
||||
progressCallback:^(long expectedContentLength, long receivedContentLength) {
|
||||
@@ -273,13 +274,13 @@ RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getConfiguration:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
resolve([[CodePushConfig current] configuration]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getCurrentPackage:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSError *error;
|
||||
@@ -293,10 +294,10 @@ RCT_EXPORT_METHOD(getCurrentPackage:(RCTPromiseResolveBlock)resolve
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(installUpdate:(NSDictionary*)updatePackage
|
||||
rollbackTimeout:(int)rollbackTimeout
|
||||
installMode:(CodePushInstallMode)installMode
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
rollbackTimeout:(int)rollbackTimeout
|
||||
installMode:(CodePushInstallMode)installMode
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
NSError *error;
|
||||
@@ -318,8 +319,8 @@ RCT_EXPORT_METHOD(installUpdate:(NSDictionary*)updatePackage
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(isFailedUpdate:(NSString *)packageHash
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject)
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
BOOL isFailedHash = [self isFailedHash:packageHash];
|
||||
resolve(@(isFailedHash));
|
||||
@@ -345,16 +346,16 @@ RCT_EXPORT_METHOD(notifyApplicationReady:(RCTPromiseResolveBlock)resolve
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(restartApp:(int)rollbackTimeout){
|
||||
// This function is exposed solely for immediately installed
|
||||
// update support, and shouldn't be consumed directly by user code.
|
||||
RCT_EXPORT_METHOD(restartImmedidateUpdate:(int)rollbackTimeout)
|
||||
{
|
||||
[self initializeUpdateWithRollbackTimeout:rollbackTimeout needsRestart:YES];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setDeploymentKey:(NSString *)deploymentKey
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
RCT_EXPORT_METHOD(restartPendingUpdate)
|
||||
{
|
||||
[[CodePushConfig current] setDeploymentKey:deploymentKey];
|
||||
resolve(nil);
|
||||
[self checkForPendingUpdate:YES];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setUsingTestFolder:(BOOL)shouldUseTestFolder)
|
||||
@@ -362,4 +363,4 @@ RCT_EXPORT_METHOD(setUsingTestFolder:(BOOL)shouldUseTestFolder)
|
||||
usingTestFolder = shouldUseTestFolder;
|
||||
}
|
||||
|
||||
@end
|
||||
@end
|
||||
55
README.md
55
README.md
@@ -124,18 +124,17 @@ When you require the `react-native-code-push` module, that object provides the f
|
||||
|
||||
* [checkForUpdate](#codepushcheckforupdate): Queries the CodePush service for an update against the configured deployment. This method returns a promise which resolves to a `RemotePackage` that can be subsequently downloaded.
|
||||
* [getCurrentPackage](#codepushgetcurrentpackage): Gets information about the currently installed package (e.g. description, installation time)
|
||||
* [notifyApplicationReady](#codepushnotifyapplicationready): Notifies the CodePush runtime that an installed update is considered successful. This is an optional API, but is useful when you want to expicitly enable "rollback protection" in the event that an exception occurs in any code that you've deployed to production
|
||||
* [restartApp](#codepushrestartapp): Installs a pending update by immediately restarting the app.
|
||||
* [setDeploymentKey](#codepushsetdeploymentkey): Dynamically updates the deployment key that the CodePush runtime will use to query for app updates.
|
||||
* [notifyApplicationReady](#codepushnotifyapplicationready): Notifies the CodePush runtime that an installed update is considered successful. This is an optional API, but is useful when you want to expicitly enable "rollback protection" in the event that an exception occurs in any code that you've deployed to production.
|
||||
* [restartPendingUpdate](#codepushrestartPendingUpdate): Conditionally restarts the app if a previously installed update is currently pending (e.g. it was installed using the `ON_NEXT_RESTART` or `ON_NEXT_RESUME` modes, and the user hasn't restarted or resumed the app yet).
|
||||
* [sync](#codepushsync): Allows checking for an update, downloading it and installing it, all with a single call. Unless you need custom UI and/or behavior, we recommend most developers to use this method when integrating CodePush into their apps
|
||||
|
||||
#### codePush.checkForUpdate
|
||||
|
||||
```javascript
|
||||
codePush.checkForUpdate(): Promise<RemotePackage>;
|
||||
codePush.checkForUpdate(deploymentKey: String = null): Promise<RemotePackage>;
|
||||
```
|
||||
|
||||
Queries the CodePush service for an update against the configured deployment. This method returns a promise which resolves to a `RemotePackage` that can be subsequently downloaded.
|
||||
Queries the CodePush service for an update using the deployment configured either in your `Info.plist` file or specified using the optional `deploymentKey` parameter. This method returns a promise which resolves to a `RemotePackage` that can be subsequently downloaded.
|
||||
|
||||
`checkForUpdate` returns a Promise that resolves to one of two values:
|
||||
|
||||
@@ -175,39 +174,18 @@ Notifies the CodePush runtime that an update is considered successful, and there
|
||||
|
||||
If the `rollbackTimeout` parameter was not specified, the CodePush runtime will not enforce any automatic rollback behavior, and therefore, calling this function is not required and will result in a no-op.
|
||||
|
||||
#### codePush.restartApp
|
||||
|
||||
```javascript
|
||||
codePush.restartApp(rollbackTimeout: Number = 0): void;
|
||||
```
|
||||
|
||||
Installs the pending update (if applicable) by immediately restarting the app, and optionally starting the rollback timer. This method is for advanced scenarios, and is useful when the following conditions are true:
|
||||
|
||||
1. Your app is specifying an install mode value of `ON_NEXT_RESTART` when calling `sync` or `LocalPackage.install`, which has the effect of not applying your update until the app has been restarted (by either the end-user or OS)
|
||||
2. You have an app-specific user event (e.g. the end-user navigated back to the app's home page) that allows you to apply the update in an unobtrusive way, and potentially gets the update in front of the end-user sooner then waiting until the next restart.
|
||||
|
||||
The `rollbackTimeout` parameter has the same behavior as the equivalent in the `sync` and `checkForUpdate` method, and allows your app to have control over the point that an update is installed, while still benefitting from rollback production.
|
||||
|
||||
#### codePush.setDeploymentKey
|
||||
|
||||
```javascript
|
||||
codePush.setDeploymentKey(deploymentKey: String): Promise<void>;
|
||||
```
|
||||
|
||||
Dynamically updates the deployment key that the CodePush runtime will use to query for app updates. This is beneficial if your app has a default deployment key which you added to your `Info.plist` file, but you want to dynamically change it at runtime based on some app-specific policy (e.g. you want to give early access to certain users, by pointing them at your staging deployment).
|
||||
|
||||
The method simply takes a string representing the new deployment, and returns a `Promise` that will resolve once the specified deployment key has been applied, and calls to `sync` and/or `checkForUpdate` could be successfully called.
|
||||
|
||||
Example Usage:
|
||||
|
||||
```javascript
|
||||
codePush.setDeploymentKey("SOME_VALID_KEY_VALUE").then(() => {
|
||||
// The following call to sync with query the updated
|
||||
// app deployment for an update
|
||||
codePush.sync();
|
||||
});
|
||||
|
||||
```
|
||||
#### codePush.restartPendingUpdate
|
||||
|
||||
```javascript
|
||||
codePush.restartPendingUpdate(): void;
|
||||
```
|
||||
|
||||
Installs the pending update (if applicable) by immediately restarting the app, and optionally starting the rollback timer. This method is for advanced scenarios, and is only useful when the following conditions are true:
|
||||
|
||||
1. Your app is specifying an install mode value of `ON_NEXT_RESTART` or `ON_NEXT_RESUME` when calling the `sync` or `LocalPackage.install` methods. This has the effect of not applying your update until the app has been restarted (by either the end-user or OS) or resumed, and therefore, the update won't be immediately displayed to the end-user .
|
||||
2. You have an app-specific user event (e.g. the end-user navigated back to the app's home route) that allows you to apply the update in an unobtrusive way, and potentially gets the update in front of the end-user sooner then waiting until the next restart or resume.
|
||||
|
||||
If you call this method, and there isn't a pending update, it will result in a no-op. Otherwise, the app will be restarted in order to display the update to the end-user.
|
||||
|
||||
#### codePush.sync
|
||||
|
||||
@@ -226,6 +204,7 @@ If you want to pivot whether you check and/or download an available update based
|
||||
|
||||
The method accepts an options object that allows you to customize numerous aspects of the default behavior, all of which provide sensible values by default:
|
||||
|
||||
* __deploymentKey__ (String) - Specifies the deployment key you want to query for an update against. By default, this value is derived from the `Info.plist` file, but this option allows you to override it from the script-side if you need to dynamically change your app's current deployment.
|
||||
* __ignoreFailedUpdates__ (Boolean) - Indicates whether you would like to automatically ignored updates which are available, but have been previously attemped to install, but failed. Defaults to `true`.
|
||||
* __installMode__ (CodePush.InstallMode) - Indicates whether you would like to restart the app immediately after the update has been installed, or wait until the next app resume or restart. Defaults to `CodePush.InstallMode.ON_NEXT_RESTART`
|
||||
* __rollbackTimeout__ (Number) - The number of seconds that you want the runtime to wait after an update has been installed before considering it failed and rolling it back. Defaults to `0`, which disables rollback protection.
|
||||
|
||||
@@ -40,8 +40,8 @@ module.exports = (NativeCodePush) => {
|
||||
.then(function() {
|
||||
updateInstalledCallback && updateInstalledCallback();
|
||||
if (installMode == NativeCodePush.codePushInstallModeImmediate) {
|
||||
NativeCodePush.restartApp(rollbackTimeout);
|
||||
}
|
||||
NativeCodePush.restartImmedidateUpdate(rollbackTimeout);
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user