Skip to content
This repository has been archived by the owner on Oct 7, 2024. It is now read-only.

Commit

Permalink
updated sync
Browse files Browse the repository at this point in the history
  • Loading branch information
geof90 committed Nov 18, 2015
1 parent ff891db commit a974075
Show file tree
Hide file tree
Showing 20 changed files with 266 additions and 156 deletions.
10 changes: 5 additions & 5 deletions CodePush.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ failCallback:(void (^)(NSError *err))failCallback;

@interface CodePushPackage : NSObject

+ (void)applyPackage:(NSDictionary *)updatePackage
+ (void)installPackage:(NSDictionary *)updatePackage
error:(NSError **)error;

+ (NSDictionary *)getCurrentPackage:(NSError **)error;
Expand All @@ -72,8 +72,8 @@ failCallback:(void (^)(NSError *err))failCallback;

@end

typedef NS_ENUM(NSInteger, CodePushRestartMode) {
CodePushRestartModeNone,
CodePushRestartModeImmediate,
CodePushRestartModeOnNextResume
typedef NS_ENUM(NSInteger, CodePushInstallMode) {
CodePushInstallModeImmediate,
CodePushInstallModeOnNextRestart,
CodePushInstallModeOnNextResume
};
131 changes: 91 additions & 40 deletions CodePush.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function getCurrentPackage() {
return NativeCodePush.isFailedUpdate(currentPackage.packageHash);
})
.then((failedUpdate) => {
localPackage.failedApply = failedUpdate;
localPackage.failedInstall = failedUpdate;
return NativeCodePush.isFirstRun(localPackage.packageHash);
})
.then((isFirstRun) => {
Expand Down Expand Up @@ -98,7 +98,7 @@ function checkForUpdate() {
}

// Ignore updates that require a newer app version,
// since the end-user couldn't reliably apply it
// since the end-user couldn't reliably install it
if (!update || update.updateAppVersion) {
return resolve(null);
}
Expand All @@ -107,7 +107,7 @@ function checkForUpdate() {

NativeCodePush.isFailedUpdate(update.packageHash)
.then((isFailedHash) => {
update.failedApply = isFailedHash;
update.failedInstall = isFailedHash;
resolve(update);
})
.catch(reject)
Expand All @@ -126,72 +126,106 @@ function checkForUpdate() {
* releases, and displaying a standard confirmation UI to the end-user
* when an update is available.
*/
function sync(options = {}) {
function sync(options = {}, onSyncStatusChange, onDownloadProgress) {
var syncOptions = {
descriptionPrefix: " Description: ",
appendReleaseDescription: false,

ignoreFailedUpdates: true,

mandatoryContinueButtonLabel: "Continue",
mandatoryUpdateMessage: "An update is available that must be installed.",

optionalIgnoreButtonLabel: "Ignore",
optionalInstallButtonLabel: "Install",
optionalUpdateMessage: "An update is available. Would you like to install it?",

installMode: CodePush.InstallMode.ON_NEXT_RESTART,
rollbackTimeout: 0,

updateTitle: "Update available",
updateDialog: null,

...options
};


onSyncStatusChange = typeof onSyncStatusChange == "function"
? onSyncStatusChange
: function(syncStatus) {
switch(syncStatus) {
case CodePush.SyncStatus.CHECKING_FOR_UPDATE:
console.log("Checking for update.");
break;
case CodePush.SyncStatus.DOWNLOADING_PACKAGE:
console.log("Downloading package.");
break;
case CodePush.SyncStatus.AWAITING_USER_ACTION:
console.log("Awaiting user action.");
break;
case CodePush.SyncStatus.INSTALLING_UPDATE:
console.log("Installing update.");
break;
case CodePush.SyncStatus.IDLE:
console.log("Sync is idle.");
break;
}
};

onDownloadProgress = typeof onDownloadProgress == "function"
? onDownloadProgress
: function(downloadProgress) {
console.log(`Expecting ${downloadProgress.totalBytes} bytes, received ${downloadProgress.receivedBytes} bytes.`);
};

return new Promise((resolve, reject) => {
onSyncStatusChange(CodePush.SyncStatus.CHECKING_FOR_UPDATE);
checkForUpdate()
.then((remotePackage) => {
if (!remotePackage || (remotePackage.failedApply && syncOptions.ignoreFailedUpdates)) {
resolve(CodePush.SyncStatus.UP_TO_DATE);
var doDownloadAndInstall = () => {
onSyncStatusChange(CodePush.SyncStatus.DOWNLOADING_PACKAGE);
remotePackage.download(onDownloadProgress)
.then((localPackage) => {
onSyncStatusChange(CodePush.SyncStatus.INSTALLING_UPDATE);
return localPackage.install(syncOptions.rollbackTimeout, syncOptions.installMode)
})
.then(() => {
onSyncStatusChange(CodePush.SyncStatus.IDLE);
resolve(CodePush.SyncResult.UPDATE_INSTALLED)
})
.catch(reject)
.done();
}
else {

if (!remotePackage || (remotePackage.failedInstall && syncOptions.ignoreFailedUpdates)) {
onSyncStatusChange(CodePush.SyncStatus.IDLE);
resolve(CodePush.SyncResult.UP_TO_DATE);
}
else if (syncOptions.updateNotification) {
syncOptions.updateNotification = Object.assign(CodePush.DEFAULT_UPDATE_DIALOG, syncOptions.updateNotification);

var message = null;
var dialogButtons = [
{
text: null,
onPress: () => {
remotePackage.download()
.then((localPackage) => {
resolve(CodePush.SyncStatus.UPDATE_APPLIED)
return localPackage.apply(syncOptions.rollbackTimeout);
})
.catch(reject)
.done();
doDownloadAndInstall();
}
}
];

if (remotePackage.isMandatory) {
message = syncOptions.mandatoryUpdateMessage;
message = syncOptions.updateNotification.mandatoryUpdateMessage;
dialogButtons[0].text = syncOptions.mandatoryContinueButtonLabel;
} else {
message = syncOptions.optionalUpdateMessage;
dialogButtons[0].text = syncOptions.optionalInstallButtonLabel;
message = syncOptions.updateNotification.optionalUpdateMessage;
dialogButtons[0].text = syncOptions.updateNotification.optionalInstallButtonLabel;

// Since this is an optional update, add another button
// to allow the end-user to ignore it
dialogButtons.push({
text: syncOptions.optionalIgnoreButtonLabel,
onPress: () => resolve(CodePush.SyncStatus.UPDATE_IGNORED)
text: syncOptions.updateNotification.optionalIgnoreButtonLabel,
onPress: () => resolve(CodePush.SyncResult.UPDATE_IGNORED)
});
}

// If the update has a description, and the developer
// explicitly chose to display it, then set that as the message
if (syncOptions.appendReleaseDescription && remotePackage.description) {
message += `${syncOptions.descriptionPrefix} ${remotePackage.description}`;
if (syncOptions.updateNotification.appendReleaseDescription && remotePackage.description) {
message += `${syncOptions.updateNotification.descriptionPrefix} ${remotePackage.description}`;
}

onSyncStatusChange(CodePush.SyncStatus.AWAITING_USER_ACTION);
AlertIOS.alert(syncOptions.updateTitle, message, dialogButtons);
} else {
doDownloadAndInstall();
}
})
.catch(reject)
Expand All @@ -206,15 +240,32 @@ var CodePush = {
notifyApplicationReady: NativeCodePush.notifyApplicationReady,
setUpTestDependencies: setUpTestDependencies,
sync: sync,
RestartMode: {
NONE: NativeCodePush.codePushRestartModeNone, // Don't artificially restart the app. Allow the update to be "picked up" on the next app restart
IMMEDIATE: NativeCodePush.codePushRestartModeImmediate, // Restart the app immediately
ON_NEXT_RESUME: NativeCodePush.codePushRestartModeOnNextResume // Restart the app the next time it is resumed from the background
InstallMode: {
IMMEDIATE: NativeCodePush.codePushInstallModeImmediate, // Restart the app immediately
ON_NEXT_RESTART: NativeCodePush.codePushInstallModeOnNextRestart, // Don't artificially restart the app. Allow the update to be "picked up" on the next app restart
ON_NEXT_RESUME: NativeCodePush.codePushInstallModeOnNextResume // Restart the app the next time it is resumed from the background
},
SyncStatus: {
SyncResult: {
UP_TO_DATE: 0, // The running app is up-to-date
UPDATE_IGNORED: 1, // The app had an optional update and the end-user chose to ignore it
UPDATE_APPLIED: 2 // The app had an optional/mandatory update that was successfully downloaded and is about to be applied
UPDATE_INSTALLED: 2 // The app had an optional/mandatory update that was successfully downloaded and is about to be installed.
},
SyncStatus: {
CHECKING_FOR_UPDATE: 1,
AWAITING_USER_ACTION: 2,
DOWNLOADING_PACKAGE: 3,
INSTALLING_UPDATE: 4,
IDLE: 5
},
DEFAULT_UPDATE_DIALOG: {
appendReleaseDescription: false,
descriptionPrefix: " Description: ",
mandatoryContinueButtonLabel: "Continue",
mandatoryUpdateMessage: "An update is available that must be installed.",
optionalIgnoreButtonLabel: "Ignore",
optionalInstallButtonLabel: "Install",
optionalUpdateMessage: "An update is available. Would you like to install it?",
updateTitle: "Update available",
}
};

Expand Down
24 changes: 13 additions & 11 deletions CodePush.m
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,11 @@ - (void)checkForPendingUpdateDuringResume

- (NSDictionary *)constantsToExport
{
// Export the values of the CodePushRestartMode enum
// Export the values of the CodePushInstallMode enum
// so that the script-side can easily stay in sync
return @{ @"codePushRestartModeNone": @(CodePushRestartModeNone),
@"codePushRestartModeImmediate": @(CodePushRestartModeImmediate),
@"codePushRestartModeOnNextResume": @(CodePushRestartModeOnNextResume)
return @{ @"codePushInstallModeOnNextRestart": @(CodePushInstallModeOnNextRestart),
@"codePushInstallModeImmediate": @(CodePushInstallModeImmediate),
@"codePushInstallModeOnNextResume": @(CodePushInstallModeOnNextResume)
};
};

Expand All @@ -124,7 +124,7 @@ - (CodePush *)init
if (self) {
// Do an async check to see whether
// we need to start the rollback timer
// due to a pending update being applied at start
// due to a pending update being installed at start
[self checkForPendingUpdate:NO];

// Register for app resume notifications so that we
Expand Down Expand Up @@ -204,7 +204,7 @@ - (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".
// was installed, but hasn't yet become "active".
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
NSDictionary *pendingUpdate = [[NSDictionary alloc] initWithObjectsAndKeys:
packageHash,PendingUpdateHashKey,
Expand All @@ -225,26 +225,28 @@ - (void)startRollbackTimer:(int)rollbackTimeout
}

// JavaScript-exported module methods
RCT_EXPORT_METHOD(applyUpdate:(NSDictionary*)updatePackage
RCT_EXPORT_METHOD(installUpdate:(NSDictionary*)updatePackage
rollbackTimeout:(int)rollbackTimeout
restartMode:(CodePushRestartMode)restartMode
installMode:(CodePushInstallMode)installMode
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSError *error;
[CodePushPackage applyPackage:updatePackage
[CodePushPackage installPackage:updatePackage
error:&error];

if (error) {
reject(error);
} else {
if (restartMode == CodePushRestartModeImmediate) {
if (installMode == CodePushInstallModeImmediate) {
[self initializeUpdateWithRollbackTimeout:rollbackTimeout needsRestart:YES];
} else {
_resumablePendingUpdateAvailable = (restartMode == CodePushRestartModeOnNextResume);
_resumablePendingUpdateAvailable = (installMode == CodePushInstallModeOnNextResume);
[self savePendingUpdate:updatePackage[@"packageHash"]
rollbackTimeout:rollbackTimeout];
// Signal to JS that the update has been applied.
resolve(nil);
}
}
});
Expand Down
8 changes: 4 additions & 4 deletions CodePush.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

/* Begin PBXBuildFile section */
13BE3DEE1AC21097009241FE /* CodePush.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BE3DED1AC21097009241FE /* CodePush.m */; };
1B23B9141BF9267B000BB2F0 /* RCTConvert+CodePushRestartMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B23B9131BF9267B000BB2F0 /* RCTConvert+CodePushRestartMode.m */; };
1B23B9141BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B23B9131BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m */; };
54FFEDE01BF550630061DD23 /* CodePushDownloadHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 54FFEDDF1BF550630061DD23 /* CodePushDownloadHandler.m */; };
810D4E6D1B96935000B397E9 /* CodePushPackage.m in Sources */ = {isa = PBXBuildFile; fileRef = 810D4E6C1B96935000B397E9 /* CodePushPackage.m */; };
81D51F3A1B6181C2000DA084 /* CodePushConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 81D51F391B6181C2000DA084 /* CodePushConfig.m */; };
Expand All @@ -30,7 +30,7 @@
134814201AA4EA6300B7C361 /* libCodePush.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCodePush.a; sourceTree = BUILT_PRODUCTS_DIR; };
13BE3DEC1AC21097009241FE /* CodePush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodePush.h; sourceTree = "<group>"; };
13BE3DED1AC21097009241FE /* CodePush.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodePush.m; sourceTree = "<group>"; };
1B23B9131BF9267B000BB2F0 /* RCTConvert+CodePushRestartMode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+CodePushRestartMode.m"; sourceTree = "<group>"; };
1B23B9131BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+CodePushInstallMode.m"; sourceTree = "<group>"; };
54FFEDDF1BF550630061DD23 /* CodePushDownloadHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodePushDownloadHandler.m; sourceTree = "<group>"; };
810D4E6C1B96935000B397E9 /* CodePushPackage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodePushPackage.m; sourceTree = "<group>"; };
81D51F391B6181C2000DA084 /* CodePushConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodePushConfig.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -58,7 +58,7 @@
58B511D21A9E6C8500147676 = {
isa = PBXGroup;
children = (
1B23B9131BF9267B000BB2F0 /* RCTConvert+CodePushRestartMode.m */,
1B23B9131BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m */,
54FFEDDF1BF550630061DD23 /* CodePushDownloadHandler.m */,
810D4E6C1B96935000B397E9 /* CodePushPackage.m */,
81D51F391B6181C2000DA084 /* CodePushConfig.m */,
Expand Down Expand Up @@ -124,7 +124,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1B23B9141BF9267B000BB2F0 /* RCTConvert+CodePushRestartMode.m in Sources */,
1B23B9141BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m in Sources */,
81D51F3A1B6181C2000DA084 /* CodePushConfig.m in Sources */,
54FFEDE01BF550630061DD23 /* CodePushDownloadHandler.m in Sources */,
13BE3DEE1AC21097009241FE /* CodePush.m in Sources */,
Expand Down
2 changes: 1 addition & 1 deletion CodePushPackage.m
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ + (void)downloadPackage:(NSDictionary *)updatePackage
[downloadHandler download:updatePackage[@"downloadUrl"]];
}

+ (void)applyPackage:(NSDictionary *)updatePackage
+ (void)installPackage:(NSDictionary *)updatePackage
error:(NSError **)error
{
NSString *packageHash = updatePackage[@"packageHash" ];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
544161591B8BCA81000D9E25 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
5451ACBA1B86A5B600E2A7DF /* QueryUpdateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5451ACB81B86A5B600E2A7DF /* QueryUpdateTests.m */; };
5451ACEC1B86E40A00E2A7DF /* libRCTTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5451ACEB1B86E34300E2A7DF /* libRCTTest.a */; };
54D774BA1B87DAF800F2ABF8 /* ApplyUpdateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 54D774B91B87DAF800F2ABF8 /* ApplyUpdateTests.m */; };
54D774BA1B87DAF800F2ABF8 /* InstallUpdateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 54D774B91B87DAF800F2ABF8 /* InstallUpdateTests.m */; };
54F5F2B41BF6B45D007C3CEA /* DownloadProgressTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 54F5F2B31BF6B45D007C3CEA /* DownloadProgressTests.m */; settings = {ASSET_TAGS = (); }; };
81551E1B1B3B428000F5B9F1 /* libCodePush.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 81551E0F1B3B427200F5B9F1 /* libCodePush.a */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -151,7 +151,7 @@
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
5451ACB81B86A5B600E2A7DF /* QueryUpdateTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QueryUpdateTests.m; sourceTree = "<group>"; };
5451ACE61B86E34300E2A7DF /* RCTTest.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTTest.xcodeproj; path = "node_modules/react-native/Libraries/RCTTest/RCTTest.xcodeproj"; sourceTree = "<group>"; };
54D774B91B87DAF800F2ABF8 /* ApplyUpdateTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ApplyUpdateTests.m; sourceTree = "<group>"; };
54D774B91B87DAF800F2ABF8 /* InstallUpdateTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InstallUpdateTests.m; sourceTree = "<group>"; };
54F5F2B31BF6B45D007C3CEA /* DownloadProgressTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DownloadProgressTests.m; sourceTree = "<group>"; };
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
81551E0A1B3B427200F5B9F1 /* CodePush.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CodePush.xcodeproj; path = ../../CodePush.xcodeproj; sourceTree = "<group>"; };
Expand Down Expand Up @@ -242,7 +242,7 @@
children = (
54F5F2B31BF6B45D007C3CEA /* DownloadProgressTests.m */,
5451ACB81B86A5B600E2A7DF /* QueryUpdateTests.m */,
54D774B91B87DAF800F2ABF8 /* ApplyUpdateTests.m */,
54D774B91B87DAF800F2ABF8 /* InstallUpdateTests.m */,
00E356F01AD99517003FC87E /* Supporting Files */,
);
path = CodePushDemoAppTests;
Expand Down Expand Up @@ -612,7 +612,7 @@
files = (
5451ACBA1B86A5B600E2A7DF /* QueryUpdateTests.m in Sources */,
54F5F2B41BF6B45D007C3CEA /* DownloadProgressTests.m in Sources */,
54D774BA1B87DAF800F2ABF8 /* ApplyUpdateTests.m in Sources */,
54D774BA1B87DAF800F2ABF8 /* InstallUpdateTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Loading

0 comments on commit a974075

Please sign in to comment.