Merge pull request #43 from Microsoft/applyImmediately

Adding new restartImmediately flag to the apply method
This commit is contained in:
Jonathan Carter
2015-11-10 16:26:50 -08:00
3 changed files with 75 additions and 19 deletions

View File

@@ -11,7 +11,8 @@ NSTimer *_timer;
BOOL usingTestFolder = NO;
BOOL didUpdate = NO;
NSString * const FailedUpdatesKey = @"FAILED_UPDATES";
NSString * const FailedUpdatesKey = @"CODE_PUSH_FAILED_UPDATES";
NSString * const PendingUpdateKey = @"CODE_PUSH_PENDING_UPDATE";
NSString * const UpdateBundleFileName = @"app.jsbundle";
@synthesize bridge = _bridge;
@@ -57,6 +58,51 @@ NSString * const UpdateBundleFileName = @"app.jsbundle";
});
}
- (CodePush *)init
{
self = [super init];
if (self) {
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
NSDictionary *pendingUpdate = [preferences objectForKey:PendingUpdateKey];
if (pendingUpdate)
{
NSError *error;
NSString *pendingHash = pendingUpdate[@"hash"];
NSString *currentHash = [CodePushPackage getCurrentPackageHash:&error];
// If the current hash is equivalent to the pending hash, then the app
// restart "picked up" the new update, but we need to kick off the
// rollback timer and ensure that the necessary state is setup.
if ([pendingHash isEqualToString:currentHash]) {
int rollbackTimeout = [pendingUpdate[@"rollbackTimeout"] intValue];
[self initializeUpdateWithRollbackTimeout:rollbackTimeout needsRestart:NO];
// Clear the pending update and sync
[preferences removeObjectForKey:PendingUpdateKey];
[preferences synchronize];
}
}
}
return self;
}
- (void)initializeUpdateWithRollbackTimeout:(int)rollbackTimeout needsRestart:(BOOL)needsRestart {
didUpdate = YES;
if (needsRestart) {
[self loadBundle];
}
if (0 != rollbackTimeout) {
dispatch_async(dispatch_get_main_queue(), ^{
[self startRollbackTimer:rollbackTimeout];
});
}
}
- (BOOL)isFailedHash:(NSString*)packageHash {
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
NSMutableArray *failedUpdates = [preferences objectForKey:FailedUpdatesKey];
@@ -101,6 +147,19 @@ NSString * const UpdateBundleFileName = @"app.jsbundle";
[preferences synchronize];
}
- (void)savePendingUpdate:(NSString *)packageHash
rollbackTimeout:(int)rollbackTimeout {
// Since we're not restarting, we need to store the fact that the update
// was applied, but hasn't yet become "active".
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
NSDictionary *pendingUpdate = [[NSDictionary alloc] initWithObjectsAndKeys:
packageHash,@"hash",
rollbackTimeout,@"rollbackTimeout", nil];
[preferences setObject:pendingUpdate forKey:PendingUpdateKey];
[preferences synchronize];
}
- (void)startRollbackTimer:(int)rollbackTimeout
{
double timeoutInSeconds = rollbackTimeout / 1000;
@@ -113,11 +172,11 @@ NSString * const UpdateBundleFileName = @"app.jsbundle";
// JavaScript-exported module methods
RCT_EXPORT_METHOD(applyUpdate:(NSDictionary*)updatePackage
rollbackTimeout:(int)rollbackTimeout
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
rollbackTimeout:(int)rollbackTimeout
restartImmediately:(BOOL)restartImmediately
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSError *error;
[CodePushPackage applyPackage:updatePackage
@@ -126,14 +185,10 @@ RCT_EXPORT_METHOD(applyUpdate:(NSDictionary*)updatePackage
if (error) {
reject(error);
} else {
didUpdate = YES;
[self loadBundle];
if (0 != rollbackTimeout) {
dispatch_async(dispatch_get_main_queue(), ^{
[self startRollbackTimer:rollbackTimeout];
});
if (restartImmediately) {
[self initializeUpdateWithRollbackTimeout:rollbackTimeout needsRestart:YES];
} else {
[self savePendingUpdate:updatePackage[@"packageHash"] rollbackTimeout:rollbackTimeout];
}
}
});

View File

@@ -248,10 +248,11 @@ Contains details about an update package that has been downloaded locally or alr
- __isFirstRun__: Flag indicating whether this is the first time the package has been run after being applied. (Boolean) This is useful for determining whether you would like to show a "What's New?" UI to the end-user after applying an update.
##### Methods
- __apply(rollbackTimeout): Promise__: Applies this package to the application. The application will be reloaded with this package and on every application launch this package will be loaded.
If the rollbackTimeout parameter is provided, the application will wait for a `notifyApplicationReady` for the given number of milliseconds.
If `notifyApplicationReady` is called before the time period specified by rollbackTimeout, the apply operation is considered a success.
Otherwise, the apply operation will be marked as failed, and the application is reverted to its previous version.
- __apply(rollbackTimeout: Number = 0, restartImmediately: Boolean = true): Promise<void>__: Applies this package to the application by unzipping its contents (e.g. the JS bundle) and saving it to the location on disk where the runtime expects to find the latest version of the app. If the `restartImmediately` parameter is set to `false`, the apply will complete, but it won't take effect until the next time that the app is restarted. Otherwise, the app will be immediately restarted after performing the apply, so that the end-user sees the changes.
<br /><br />
If a value greater than zero is provided to the `rollbackTimeout` parameter, the application will wait for the `notifyApplicationReady` method to be called for the given number of milliseconds.
<br /><br />
Note: The "rollback timer" doesn't start until the update has actually become active. If you pass a truthy value to the `restartImmediately` parameter, then the rollback timer will also start immediately. However, if you pass a falsey value, then the rollback timer will start the next time the app starts, not at the point that you called `apply`.
#### RemotePackage

View File

@@ -20,8 +20,8 @@ module.exports = (NativeCodePush) => {
};
var local = {
apply: function apply(rollbackTimeout = 0) {
return NativeCodePush.applyUpdate(this, rollbackTimeout);
apply: function apply(rollbackTimeout = 0, restartImmediately = true) {
return NativeCodePush.applyUpdate(this, rollbackTimeout, restartImmediately);
}
};