From d114b90f649288e34b0b5d83e3b7f3d053adca9d Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 02:51:12 -0800 Subject: [PATCH 01/16] use string comparison for date --- CodePush.m | 24 ++++++++++++++++++------ CodePushPackage.m | 5 +++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/CodePush.m b/CodePush.m index 317e310..49e64a7 100644 --- a/CodePush.m +++ b/CodePush.m @@ -24,6 +24,7 @@ static NSString *const DeploymentFailed = @"DeploymentFailed"; static NSString *const DeploymentSucceeded = @"DeploymentSucceeded"; // These keys represent the names we use to store data in NSUserDefaults +static NSString *const BinaryBundleDateKey = @"CODE_PUSH_BINARY_DATE"; static NSString *const FailedUpdatesKey = @"CODE_PUSH_FAILED_UPDATES"; static NSString *const PendingUpdateKey = @"CODE_PUSH_PENDING_UPDATE"; @@ -56,6 +57,11 @@ static NSString *const PackageIsPendingKey = @"isPending"; NSError *error; NSString *packageFile = [CodePushPackage getCurrentPackageBundlePath:&error]; NSURL *binaryJsBundleUrl = [[NSBundle mainBundle] URLForResource:resourceName withExtension:resourceExtension]; + NSDictionary *binaryFileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[binaryJsBundleUrl path] error:nil]; + NSDate *binaryDate = [binaryFileAttributes objectForKey:NSFileModificationDate]; + NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; + [preferences setObject:binaryDate forKey:FailedUpdatesKey]; + [preferences synchronize]; NSString *logMessageFormat = @"Loading JS bundle from %@"; @@ -65,10 +71,6 @@ static NSString *const PackageIsPendingKey = @"isPending"; return binaryJsBundleUrl; } - NSDictionary *binaryFileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[binaryJsBundleUrl path] error:nil]; - NSDictionary *appFileAttribs = [[NSFileManager defaultManager] attributesOfItemAtPath:packageFile error:nil]; - NSDate *binaryDate = [binaryFileAttributes objectForKey:NSFileModificationDate]; - NSDate *packageDate = [appFileAttribs objectForKey:NSFileModificationDate]; NSString *binaryAppVersion = [[CodePushConfig current] appVersion]; NSDictionary *currentPackageMetadata = [CodePushPackage getCurrentPackage:&error]; if (error || !currentPackageMetadata) { @@ -77,9 +79,11 @@ static NSString *const PackageIsPendingKey = @"isPending"; return binaryJsBundleUrl; } + NSString *packageDate = [currentPackageMetadata objectForKey:BinaryBundleDateKey]; + NSString *binaryDateString = [NSString stringWithFormat:@"%f", [binaryDate timeIntervalSince1970]]; NSString *packageAppVersion = [currentPackageMetadata objectForKey:@"appVersion"]; - if ([binaryDate compare:packageDate] == NSOrderedAscending && ([CodePush isUsingTestConfiguration] ||[binaryAppVersion isEqualToString:packageAppVersion])) { + if ([binaryDateString isEqualToString:packageDate] && ([CodePush isUsingTestConfiguration] ||[binaryAppVersion isEqualToString:packageAppVersion])) { // Return package file because it is newer than the app store binary's JS bundle NSURL *packageUrl = [[NSURL alloc] initFileURLWithPath:packageFile]; NSLog(logMessageFormat, packageUrl); @@ -362,11 +366,19 @@ static NSString *const PackageIsPendingKey = @"isPending"; /* * This is native-side of the RemotePackage.download method */ -RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage +RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)immutableUpdatePackage resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { dispatch_async(dispatch_get_main_queue(), ^{ + NSDictionary* updatePackage = [immutableUpdatePackage mutableCopy]; + NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; + NSDate *binaryBundleDate = [preferences objectForKey:BinaryBundleDateKey]; + if (binaryBundleDate != nil) { + [updatePackage setValue:[NSString stringWithFormat:@"%f", [binaryBundleDate timeIntervalSince1970]] + forKey:BinaryBundleDateKey]; + } + [CodePushPackage downloadPackage:updatePackage // The download is progressing forward progressCallback:^(long long expectedContentLength, long long receivedContentLength) { diff --git a/CodePushPackage.m b/CodePushPackage.m index 888c080..10a6c78 100644 --- a/CodePushPackage.m +++ b/CodePushPackage.m @@ -285,6 +285,11 @@ NSString * const UnzippedFolderName = @"unzipped"; [CodePushPackage copyEntriesInFolder:unzippedFolderPath destFolder:newPackageFolderPath error:&error]; + if (error) { + failCallback(error); + return; + } + [[NSFileManager defaultManager] removeItemAtPath:unzippedFolderPath error:&nonFailingError]; if (nonFailingError) { From e5ec7fd09b202f98c6102ff23f766b783e7efd1a Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 11:56:14 -0800 Subject: [PATCH 02/16] feedback --- CodePush.m | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/CodePush.m b/CodePush.m index 49e64a7..d3cd626 100644 --- a/CodePush.m +++ b/CodePush.m @@ -59,9 +59,7 @@ static NSString *const PackageIsPendingKey = @"isPending"; NSURL *binaryJsBundleUrl = [[NSBundle mainBundle] URLForResource:resourceName withExtension:resourceExtension]; NSDictionary *binaryFileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[binaryJsBundleUrl path] error:nil]; NSDate *binaryDate = [binaryFileAttributes objectForKey:NSFileModificationDate]; - NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; - [preferences setObject:binaryDate forKey:FailedUpdatesKey]; - [preferences synchronize]; + [self saveBinaryBundleDate:binaryDate]; NSString *logMessageFormat = @"Loading JS bundle from %@"; @@ -80,7 +78,7 @@ static NSString *const PackageIsPendingKey = @"isPending"; } NSString *packageDate = [currentPackageMetadata objectForKey:BinaryBundleDateKey]; - NSString *binaryDateString = [NSString stringWithFormat:@"%f", [binaryDate timeIntervalSince1970]]; + NSString *binaryDateString = [self getBinaryBundleDateString]; NSString *packageAppVersion = [currentPackageMetadata objectForKey:@"appVersion"]; if ([binaryDateString isEqualToString:packageDate] && ([CodePush isUsingTestConfiguration] ||[binaryAppVersion isEqualToString:packageAppVersion])) { @@ -106,6 +104,17 @@ static NSString *const PackageIsPendingKey = @"isPending"; return applicationSupportDirectory; } ++ (NSString *)getBinaryBundleDateString +{ + NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; + NSDate *binaryBundleDate = [preferences objectForKey:BinaryBundleDateKey]; + if (binaryBundleDate == nil) { + return nil; + } else { + return [NSString stringWithFormat:@"%f", [binaryBundleDate timeIntervalSince1970]]; + } +} + /* * This returns a boolean value indicating whether CodePush has * been set to run under a test configuration. @@ -115,6 +124,13 @@ static NSString *const PackageIsPendingKey = @"isPending"; return testConfigurationFlag; } ++ (void)saveBinaryBundleDate:(NSDate *)binaryBundleDate +{ + NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; + [preferences setObject:binaryBundleDate forKey:BinaryBundleDateKey]; + [preferences synchronize]; +} + + (void)setDeploymentKey:(NSString *)deploymentKey { [CodePushConfig current].deploymentKey = deploymentKey; @@ -366,20 +382,19 @@ static NSString *const PackageIsPendingKey = @"isPending"; /* * This is native-side of the RemotePackage.download method */ -RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)immutableUpdatePackage +RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { dispatch_async(dispatch_get_main_queue(), ^{ - NSDictionary* updatePackage = [immutableUpdatePackage mutableCopy]; - NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; - NSDate *binaryBundleDate = [preferences objectForKey:BinaryBundleDateKey]; + NSDictionary* mutableUpdatePackage = [updatePackage mutableCopy]; + NSString *binaryBundleDate = [CodePush getBinaryBundleDateString]; if (binaryBundleDate != nil) { - [updatePackage setValue:[NSString stringWithFormat:@"%f", [binaryBundleDate timeIntervalSince1970]] - forKey:BinaryBundleDateKey]; + [mutableUpdatePackage setValue:binaryBundleDate + forKey:BinaryBundleDateKey]; } - [CodePushPackage downloadPackage:updatePackage + [CodePushPackage downloadPackage:mutableUpdatePackage // The download is progressing forward progressCallback:^(long long expectedContentLength, long long receivedContentLength) { // Notify the script-side about the progress @@ -393,7 +408,7 @@ RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)immutableUpdatePackage // The download completed doneCallback:^{ NSError *err; - NSDictionary *newPackage = [CodePushPackage getPackage:updatePackage[PackageHashKey] error:&err]; + NSDictionary *newPackage = [CodePushPackage getPackage:mutableUpdatePackage[PackageHashKey] error:&err]; if (err) { return reject([NSString stringWithFormat: @"%lu", (long)err.code], err.localizedDescription, err); @@ -404,7 +419,7 @@ RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)immutableUpdatePackage // The download failed failCallback:^(NSError *err) { if ([CodePushPackage isCodePushError:err]) { - [self saveFailedUpdate:updatePackage]; + [self saveFailedUpdate:mutableUpdatePackage]; } reject([NSString stringWithFormat: @"%lu", (long)err.code], err.localizedDescription, err); From e29ea847e2ad0352478305104cc79e528af8b6d3 Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 11:58:33 -0800 Subject: [PATCH 03/16] feedback --- CodePush.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CodePush.m b/CodePush.m index d3cd626..85013f0 100644 --- a/CodePush.m +++ b/CodePush.m @@ -57,9 +57,7 @@ static NSString *const PackageIsPendingKey = @"isPending"; NSError *error; NSString *packageFile = [CodePushPackage getCurrentPackageBundlePath:&error]; NSURL *binaryJsBundleUrl = [[NSBundle mainBundle] URLForResource:resourceName withExtension:resourceExtension]; - NSDictionary *binaryFileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[binaryJsBundleUrl path] error:nil]; - NSDate *binaryDate = [binaryFileAttributes objectForKey:NSFileModificationDate]; - [self saveBinaryBundleDate:binaryDate]; + [self saveBinaryBundleDate:binaryJsBundleUrl]; NSString *logMessageFormat = @"Loading JS bundle from %@"; @@ -124,10 +122,12 @@ static NSString *const PackageIsPendingKey = @"isPending"; return testConfigurationFlag; } -+ (void)saveBinaryBundleDate:(NSDate *)binaryBundleDate ++ (void)saveBinaryBundleDate:(NSURL *)binaryJsBundleUrl { + NSDictionary *binaryFileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[binaryJsBundleUrl path] error:nil]; + NSDate *binaryDate = [binaryFileAttributes objectForKey:NSFileModificationDate]; NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; - [preferences setObject:binaryBundleDate forKey:BinaryBundleDateKey]; + [preferences setObject:binaryDate forKey:BinaryBundleDateKey]; [preferences synchronize]; } From b8eed11109d6f26356d60a2002544f156577b424 Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 14:13:02 -0800 Subject: [PATCH 04/16] delete before unzipping --- CodePushPackage.m | 10 +++++++++- .../CodePushDemoApp/iOS/CodePushDemoApp/Info.plist | 2 +- .../java/com/microsoft/codepush/react/FileUtils.java | 6 ++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CodePushPackage.m b/CodePushPackage.m index 10a6c78..4d1300b 100644 --- a/CodePushPackage.m +++ b/CodePushPackage.m @@ -228,8 +228,16 @@ NSString * const UnzippedFolderName = @"unzipped"; NSString * unzippedFolderPath = [CodePushPackage getUnzippedFolderPath]; NSMutableDictionary * mutableUpdatePackage = [updatePackage mutableCopy]; if (isZip) { - NSError *nonFailingError = nil; + if ([[NSFileManager defaultManager] fileExistsAtPath:unzippedFolderPath]) { + [[NSFileManager defaultManager] removeItemAtPath:unzippedFolderPath + error:&error]; + if (error) { + failCallback(error); + return; + } + } + NSError *nonFailingError = nil; [SSZipArchive unzipFileAtPath:downloadFilePath toDestination:unzippedFolderPath]; [[NSFileManager defaultManager] removeItemAtPath:downloadFilePath diff --git a/Examples/CodePushDemoApp/iOS/CodePushDemoApp/Info.plist b/Examples/CodePushDemoApp/iOS/CodePushDemoApp/Info.plist index e1033b9..6cb683d 100644 --- a/Examples/CodePushDemoApp/iOS/CodePushDemoApp/Info.plist +++ b/Examples/CodePushDemoApp/iOS/CodePushDemoApp/Info.plist @@ -44,6 +44,6 @@ NSLocationWhenInUseUsageDescription CodePushDeploymentKey - deployment-key-here + 5c73310a-cc93-4aa5-bf9f-81c6b648232c diff --git a/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java b/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java index 3275363..cde2ed7 100644 --- a/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java +++ b/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java @@ -152,9 +152,11 @@ public class FileUtils { ZipEntry entry; File destinationFolder = new File(destination); - if (!destinationFolder.exists()) { - destinationFolder.mkdirs(); + if (destinationFolder.exists()) { + deleteDirectory(destinationFolder); } + + destinationFolder.mkdirs(); byte[] buffer = new byte[WRITE_BUFFER_SIZE]; while ((entry = zipStream.getNextEntry()) != null) { From 7c351e3528f07735df7e3fcb3ef2814652cf9313 Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 14:15:22 -0800 Subject: [PATCH 05/16] delete before unzipping --- Examples/CodePushDemoApp/iOS/CodePushDemoApp/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/CodePushDemoApp/iOS/CodePushDemoApp/Info.plist b/Examples/CodePushDemoApp/iOS/CodePushDemoApp/Info.plist index 6cb683d..e1033b9 100644 --- a/Examples/CodePushDemoApp/iOS/CodePushDemoApp/Info.plist +++ b/Examples/CodePushDemoApp/iOS/CodePushDemoApp/Info.plist @@ -44,6 +44,6 @@ NSLocationWhenInUseUsageDescription CodePushDeploymentKey - 5c73310a-cc93-4aa5-bf9f-81c6b648232c + deployment-key-here From cb00cd11562a06e05dce0c541b7c90a974de7a52 Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 15:57:20 -0800 Subject: [PATCH 06/16] use static variable instead of user prefs --- CodePush.m | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/CodePush.m b/CodePush.m index 85013f0..0292ea6 100644 --- a/CodePush.m +++ b/CodePush.m @@ -18,6 +18,7 @@ RCT_EXPORT_MODULE() static BOOL needToReportRollback = NO; static BOOL isRunningBinaryVersion = NO; static BOOL testConfigurationFlag = NO; +static NSString *binaryBundleDate = nil; // These constants represent valid deployment statuses static NSString *const DeploymentFailed = @"DeploymentFailed"; @@ -57,7 +58,7 @@ static NSString *const PackageIsPendingKey = @"isPending"; NSError *error; NSString *packageFile = [CodePushPackage getCurrentPackageBundlePath:&error]; NSURL *binaryJsBundleUrl = [[NSBundle mainBundle] URLForResource:resourceName withExtension:resourceExtension]; - [self saveBinaryBundleDate:binaryJsBundleUrl]; + [self setBinaryBundleDate:binaryJsBundleUrl]; NSString *logMessageFormat = @"Loading JS bundle from %@"; @@ -76,10 +77,9 @@ static NSString *const PackageIsPendingKey = @"isPending"; } NSString *packageDate = [currentPackageMetadata objectForKey:BinaryBundleDateKey]; - NSString *binaryDateString = [self getBinaryBundleDateString]; NSString *packageAppVersion = [currentPackageMetadata objectForKey:@"appVersion"]; - if ([binaryDateString isEqualToString:packageDate] && ([CodePush isUsingTestConfiguration] ||[binaryAppVersion isEqualToString:packageAppVersion])) { + if ([binaryBundleDate isEqualToString:packageDate] && ([CodePush isUsingTestConfiguration] ||[binaryAppVersion isEqualToString:packageAppVersion])) { // Return package file because it is newer than the app store binary's JS bundle NSURL *packageUrl = [[NSURL alloc] initFileURLWithPath:packageFile]; NSLog(logMessageFormat, packageUrl); @@ -102,17 +102,6 @@ static NSString *const PackageIsPendingKey = @"isPending"; return applicationSupportDirectory; } -+ (NSString *)getBinaryBundleDateString -{ - NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; - NSDate *binaryBundleDate = [preferences objectForKey:BinaryBundleDateKey]; - if (binaryBundleDate == nil) { - return nil; - } else { - return [NSString stringWithFormat:@"%f", [binaryBundleDate timeIntervalSince1970]]; - } -} - /* * This returns a boolean value indicating whether CodePush has * been set to run under a test configuration. @@ -122,13 +111,14 @@ static NSString *const PackageIsPendingKey = @"isPending"; return testConfigurationFlag; } -+ (void)saveBinaryBundleDate:(NSURL *)binaryJsBundleUrl +/* + * This caches the binary's jsbundle modified date in memory as a string. + */ ++ (void)setBinaryBundleDate:(NSURL *)binaryJsBundleUrl { NSDictionary *binaryFileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[binaryJsBundleUrl path] error:nil]; NSDate *binaryDate = [binaryFileAttributes objectForKey:NSFileModificationDate]; - NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; - [preferences setObject:binaryDate forKey:BinaryBundleDateKey]; - [preferences synchronize]; + binaryBundleDate = [NSString stringWithFormat:@"%f", [binaryDate timeIntervalSince1970]]; } + (void)setDeploymentKey:(NSString *)deploymentKey @@ -388,7 +378,6 @@ RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage { dispatch_async(dispatch_get_main_queue(), ^{ NSDictionary* mutableUpdatePackage = [updatePackage mutableCopy]; - NSString *binaryBundleDate = [CodePush getBinaryBundleDateString]; if (binaryBundleDate != nil) { [mutableUpdatePackage setValue:binaryBundleDate forKey:BinaryBundleDateKey]; From b773e867791d98f0254f738c506ac4350594d789 Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 16:30:38 -0800 Subject: [PATCH 07/16] save resource name and extension instead --- CodePush.m | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/CodePush.m b/CodePush.m index 0292ea6..291a203 100644 --- a/CodePush.m +++ b/CodePush.m @@ -18,7 +18,6 @@ RCT_EXPORT_MODULE() static BOOL needToReportRollback = NO; static BOOL isRunningBinaryVersion = NO; static BOOL testConfigurationFlag = NO; -static NSString *binaryBundleDate = nil; // These constants represent valid deployment statuses static NSString *const DeploymentFailed = @"DeploymentFailed"; @@ -39,26 +38,39 @@ static NSString *const PendingUpdateIsLoadingKey = @"isLoading"; static NSString *const PackageHashKey = @"packageHash"; static NSString *const PackageIsPendingKey = @"isPending"; +// These values are used to save the bundleURL and extension for the JS bundle +// in the binary. +static NSString *binaryJsName = @"main"; +static NSString *binaryJsExtension = @"jsbundle"; + + #pragma mark - Public Obj-C API ++ (NSURL *)binaryJsBundleUrl +{ + return [[NSBundle mainBundle] URLForResource:binaryJsName withExtension:binaryJsExtension]; +} + + (NSURL *)bundleURL { - return [self bundleURLForResource:@"main"]; + return [self bundleURLForResource:binaryJsName]; } + (NSURL *)bundleURLForResource:(NSString *)resourceName { + binaryJsName = resourceName; return [self bundleURLForResource:resourceName - withExtension:@"jsbundle"]; + withExtension:binaryJsExtension]; } + (NSURL *)bundleURLForResource:(NSString *)resourceName withExtension:(NSString *)resourceExtension { + binaryJsName = resourceName; + binaryJsExtension = resourceExtension; NSError *error; NSString *packageFile = [CodePushPackage getCurrentPackageBundlePath:&error]; - NSURL *binaryJsBundleUrl = [[NSBundle mainBundle] URLForResource:resourceName withExtension:resourceExtension]; - [self setBinaryBundleDate:binaryJsBundleUrl]; + NSURL *binaryJsBundleUrl = [self binaryJsBundleUrl]; NSString *logMessageFormat = @"Loading JS bundle from %@"; @@ -79,7 +91,7 @@ static NSString *const PackageIsPendingKey = @"isPending"; NSString *packageDate = [currentPackageMetadata objectForKey:BinaryBundleDateKey]; NSString *packageAppVersion = [currentPackageMetadata objectForKey:@"appVersion"]; - if ([binaryBundleDate isEqualToString:packageDate] && ([CodePush isUsingTestConfiguration] ||[binaryAppVersion isEqualToString:packageAppVersion])) { + if ([[self modifiedDateStringFromFileUrl:binaryJsBundleUrl] isEqualToString:packageDate] && ([CodePush isUsingTestConfiguration] ||[binaryAppVersion isEqualToString:packageAppVersion])) { // Return package file because it is newer than the app store binary's JS bundle NSURL *packageUrl = [[NSURL alloc] initFileURLWithPath:packageFile]; NSLog(logMessageFormat, packageUrl); @@ -112,13 +124,17 @@ static NSString *const PackageIsPendingKey = @"isPending"; } /* - * This caches the binary's jsbundle modified date in memory as a string. + * This returns the modified date as a string for a given file URL. */ -+ (void)setBinaryBundleDate:(NSURL *)binaryJsBundleUrl ++ (NSString *)modifiedDateStringFromFileUrl:(NSURL *)fileUrl { - NSDictionary *binaryFileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[binaryJsBundleUrl path] error:nil]; - NSDate *binaryDate = [binaryFileAttributes objectForKey:NSFileModificationDate]; - binaryBundleDate = [NSString stringWithFormat:@"%f", [binaryDate timeIntervalSince1970]]; + if (fileUrl != nil) { + NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[fileUrl path] error:nil]; + NSDate *modifiedDate = [fileAttributes objectForKey:NSFileModificationDate]; + return [NSString stringWithFormat:@"%f", [modifiedDate timeIntervalSince1970]]; + } else { + return nil; + } } + (void)setDeploymentKey:(NSString *)deploymentKey @@ -377,9 +393,10 @@ RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage rejecter:(RCTPromiseRejectBlock)reject) { dispatch_async(dispatch_get_main_queue(), ^{ - NSDictionary* mutableUpdatePackage = [updatePackage mutableCopy]; - if (binaryBundleDate != nil) { - [mutableUpdatePackage setValue:binaryBundleDate + NSDictionary *mutableUpdatePackage = [updatePackage mutableCopy]; + NSURL *binaryJsBundleUrl = [CodePush binaryJsBundleUrl]; + if (binaryJsBundleUrl != nil) { + [mutableUpdatePackage setValue:[CodePush modifiedDateStringFromFileUrl:binaryJsBundleUrl] forKey:BinaryBundleDateKey]; } From a067ca6c8c58ba2c40c089d05ec32eedeacff77b Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 16:33:11 -0800 Subject: [PATCH 08/16] rename binary bundle date key --- CodePush.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodePush.m b/CodePush.m index 291a203..f116635 100644 --- a/CodePush.m +++ b/CodePush.m @@ -24,7 +24,6 @@ static NSString *const DeploymentFailed = @"DeploymentFailed"; static NSString *const DeploymentSucceeded = @"DeploymentSucceeded"; // These keys represent the names we use to store data in NSUserDefaults -static NSString *const BinaryBundleDateKey = @"CODE_PUSH_BINARY_DATE"; static NSString *const FailedUpdatesKey = @"CODE_PUSH_FAILED_UPDATES"; static NSString *const PendingUpdateKey = @"CODE_PUSH_PENDING_UPDATE"; @@ -37,6 +36,7 @@ static NSString *const PendingUpdateIsLoadingKey = @"isLoading"; // that is associated with an update's package. static NSString *const PackageHashKey = @"packageHash"; static NSString *const PackageIsPendingKey = @"isPending"; +static NSString *const BinaryBundleDateKey = @"binaryDate"; // These values are used to save the bundleURL and extension for the JS bundle // in the binary. From 9ea68b7d7abfb1e6bceb9918af308984c050b193 Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 16:57:42 -0800 Subject: [PATCH 09/16] feedback --- CodePush.m | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/CodePush.m b/CodePush.m index f116635..0f40f6f 100644 --- a/CodePush.m +++ b/CodePush.m @@ -34,64 +34,64 @@ static NSString *const PendingUpdateIsLoadingKey = @"isLoading"; // These keys are used to inspect/augment the metadata // that is associated with an update's package. +static NSString *const BinaryBundleDateKey = @"binaryDate"; static NSString *const PackageHashKey = @"packageHash"; static NSString *const PackageIsPendingKey = @"isPending"; -static NSString *const BinaryBundleDateKey = @"binaryDate"; // These values are used to save the bundleURL and extension for the JS bundle // in the binary. -static NSString *binaryJsName = @"main"; -static NSString *binaryJsExtension = @"jsbundle"; +static NSString *bundleResourceName = @"main"; +static NSString *bundleResourceExtension = @"jsbundle"; #pragma mark - Public Obj-C API -+ (NSURL *)binaryJsBundleUrl ++ (NSURL *)binaryBundleURL { - return [[NSBundle mainBundle] URLForResource:binaryJsName withExtension:binaryJsExtension]; + return [[NSBundle mainBundle] URLForResource:bundleResourceName withExtension:bundleResourceExtension]; } + (NSURL *)bundleURL { - return [self bundleURLForResource:binaryJsName]; + return [self bundleURLForResource:bundleResourceName]; } + (NSURL *)bundleURLForResource:(NSString *)resourceName { - binaryJsName = resourceName; + bundleResourceName = resourceName; return [self bundleURLForResource:resourceName - withExtension:binaryJsExtension]; + withExtension:bundleResourceExtension]; } + (NSURL *)bundleURLForResource:(NSString *)resourceName withExtension:(NSString *)resourceExtension { - binaryJsName = resourceName; - binaryJsExtension = resourceExtension; + bundleResourceName = resourceName; + bundleResourceExtension = resourceExtension; NSError *error; NSString *packageFile = [CodePushPackage getCurrentPackageBundlePath:&error]; - NSURL *binaryJsBundleUrl = [self binaryJsBundleUrl]; + NSURL *binaryBundleURL = [self binaryBundleURL]; NSString *logMessageFormat = @"Loading JS bundle from %@"; if (error || !packageFile) { - NSLog(logMessageFormat, binaryJsBundleUrl); + NSLog(logMessageFormat, binaryBundleURL); isRunningBinaryVersion = YES; - return binaryJsBundleUrl; + return binaryBundleURL; } NSString *binaryAppVersion = [[CodePushConfig current] appVersion]; NSDictionary *currentPackageMetadata = [CodePushPackage getCurrentPackage:&error]; if (error || !currentPackageMetadata) { - NSLog(logMessageFormat, binaryJsBundleUrl); + NSLog(logMessageFormat, binaryBundleURL); isRunningBinaryVersion = YES; - return binaryJsBundleUrl; + return binaryBundleURL; } NSString *packageDate = [currentPackageMetadata objectForKey:BinaryBundleDateKey]; NSString *packageAppVersion = [currentPackageMetadata objectForKey:@"appVersion"]; - if ([[self modifiedDateStringFromFileUrl:binaryJsBundleUrl] isEqualToString:packageDate] && ([CodePush isUsingTestConfiguration] ||[binaryAppVersion isEqualToString:packageAppVersion])) { + if ([[self modifiedDateStringFromFileUrl:binaryBundleURL] isEqualToString:packageDate] && ([CodePush isUsingTestConfiguration] ||[binaryAppVersion isEqualToString:packageAppVersion])) { // Return package file because it is newer than the app store binary's JS bundle NSURL *packageUrl = [[NSURL alloc] initFileURLWithPath:packageFile]; NSLog(logMessageFormat, packageUrl); @@ -102,9 +102,9 @@ static NSString *binaryJsExtension = @"jsbundle"; [CodePush clearUpdates]; #endif - NSLog(logMessageFormat, binaryJsBundleUrl); + NSLog(logMessageFormat, binaryBundleURL); isRunningBinaryVersion = YES; - return binaryJsBundleUrl; + return binaryBundleURL; } } @@ -394,9 +394,9 @@ RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage { dispatch_async(dispatch_get_main_queue(), ^{ NSDictionary *mutableUpdatePackage = [updatePackage mutableCopy]; - NSURL *binaryJsBundleUrl = [CodePush binaryJsBundleUrl]; - if (binaryJsBundleUrl != nil) { - [mutableUpdatePackage setValue:[CodePush modifiedDateStringFromFileUrl:binaryJsBundleUrl] + NSURL *binaryBundleURL = [CodePush binaryBundleURL]; + if (binaryBundleURL != nil) { + [mutableUpdatePackage setValue:[CodePush modifiedDateStringFromFileUrl:binaryBundleURL] forKey:BinaryBundleDateKey]; } From 5986abb0a6f35e27b2d5dbbc3cf95196d609d7ca Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 16:59:50 -0800 Subject: [PATCH 10/16] feedback --- CodePush.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CodePush.m b/CodePush.m index 0f40f6f..d32b3a9 100644 --- a/CodePush.m +++ b/CodePush.m @@ -46,11 +46,6 @@ static NSString *bundleResourceExtension = @"jsbundle"; #pragma mark - Public Obj-C API -+ (NSURL *)binaryBundleURL -{ - return [[NSBundle mainBundle] URLForResource:bundleResourceName withExtension:bundleResourceExtension]; -} - + (NSURL *)bundleURL { return [self bundleURLForResource:bundleResourceName]; @@ -167,6 +162,11 @@ static NSString *bundleResourceExtension = @"jsbundle"; @synthesize bridge = _bridge; ++ (NSURL *)binaryBundleURL +{ + return [[NSBundle mainBundle] URLForResource:bundleResourceName withExtension:bundleResourceExtension]; +} + /* * This method is used by the React Native bridge to allow * our plugin to expose constants to the JS-side. In our case From cd5b5f779ffd1082a6e05b992813a8a0ffa69871 Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 17:06:09 -0800 Subject: [PATCH 11/16] sort var names --- CodePush.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CodePush.m b/CodePush.m index d32b3a9..121b052 100644 --- a/CodePush.m +++ b/CodePush.m @@ -40,9 +40,8 @@ static NSString *const PackageIsPendingKey = @"isPending"; // These values are used to save the bundleURL and extension for the JS bundle // in the binary. -static NSString *bundleResourceName = @"main"; static NSString *bundleResourceExtension = @"jsbundle"; - +static NSString *bundleResourceName = @"main"; #pragma mark - Public Obj-C API From 117a747ce4be3baa2fd1288631a6e94d793bc96e Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 17:11:18 -0800 Subject: [PATCH 12/16] pragma mark --- CodePush.m | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CodePush.m b/CodePush.m index 121b052..db086f1 100644 --- a/CodePush.m +++ b/CodePush.m @@ -15,10 +15,6 @@ RCT_EXPORT_MODULE() #pragma mark - Private constants -static BOOL needToReportRollback = NO; -static BOOL isRunningBinaryVersion = NO; -static BOOL testConfigurationFlag = NO; - // These constants represent valid deployment statuses static NSString *const DeploymentFailed = @"DeploymentFailed"; static NSString *const DeploymentSucceeded = @"DeploymentSucceeded"; @@ -38,6 +34,12 @@ static NSString *const BinaryBundleDateKey = @"binaryDate"; static NSString *const PackageHashKey = @"packageHash"; static NSString *const PackageIsPendingKey = @"isPending"; +#pragma mark - Static variables + +static BOOL needToReportRollback = NO; +static BOOL isRunningBinaryVersion = NO; +static BOOL testConfigurationFlag = NO; + // These values are used to save the bundleURL and extension for the JS bundle // in the binary. static NSString *bundleResourceExtension = @"jsbundle"; From 7a8faa2450eb6439a1e6a826b011e472ab8e15cd Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 17:12:36 -0800 Subject: [PATCH 13/16] rename function --- CodePush.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CodePush.m b/CodePush.m index db086f1..7a6e8fb 100644 --- a/CodePush.m +++ b/CodePush.m @@ -87,7 +87,7 @@ static NSString *bundleResourceName = @"main"; NSString *packageDate = [currentPackageMetadata objectForKey:BinaryBundleDateKey]; NSString *packageAppVersion = [currentPackageMetadata objectForKey:@"appVersion"]; - if ([[self modifiedDateStringFromFileUrl:binaryBundleURL] isEqualToString:packageDate] && ([CodePush isUsingTestConfiguration] ||[binaryAppVersion isEqualToString:packageAppVersion])) { + if ([[self modifiedDateStringOfFileAtUrl:binaryBundleURL] isEqualToString:packageDate] && ([CodePush isUsingTestConfiguration] ||[binaryAppVersion isEqualToString:packageAppVersion])) { // Return package file because it is newer than the app store binary's JS bundle NSURL *packageUrl = [[NSURL alloc] initFileURLWithPath:packageFile]; NSLog(logMessageFormat, packageUrl); @@ -122,7 +122,7 @@ static NSString *bundleResourceName = @"main"; /* * This returns the modified date as a string for a given file URL. */ -+ (NSString *)modifiedDateStringFromFileUrl:(NSURL *)fileUrl ++ (NSString *)modifiedDateStringOfFileAtUrl:(NSURL *)fileUrl { if (fileUrl != nil) { NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[fileUrl path] error:nil]; @@ -397,7 +397,7 @@ RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage NSDictionary *mutableUpdatePackage = [updatePackage mutableCopy]; NSURL *binaryBundleURL = [CodePush binaryBundleURL]; if (binaryBundleURL != nil) { - [mutableUpdatePackage setValue:[CodePush modifiedDateStringFromFileUrl:binaryBundleURL] + [mutableUpdatePackage setValue:[CodePush modifiedDateStringOfFileAtUrl:binaryBundleURL] forKey:BinaryBundleDateKey]; } From dc70b12a293f96be30fc74d5c2e1e663312167f9 Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 17:13:37 -0800 Subject: [PATCH 14/16] sort vars --- CodePush.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodePush.m b/CodePush.m index 7a6e8fb..105f4ce 100644 --- a/CodePush.m +++ b/CodePush.m @@ -36,8 +36,8 @@ static NSString *const PackageIsPendingKey = @"isPending"; #pragma mark - Static variables -static BOOL needToReportRollback = NO; static BOOL isRunningBinaryVersion = NO; +static BOOL needToReportRollback = NO; static BOOL testConfigurationFlag = NO; // These values are used to save the bundleURL and extension for the JS bundle From 132bf006279deb1d0318bc2b28b376a87ce84042 Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 17:18:15 -0800 Subject: [PATCH 15/16] move to private --- CodePush.m | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/CodePush.m b/CodePush.m index 105f4ce..09cec25 100644 --- a/CodePush.m +++ b/CodePush.m @@ -119,20 +119,6 @@ static NSString *bundleResourceName = @"main"; return testConfigurationFlag; } -/* - * This returns the modified date as a string for a given file URL. - */ -+ (NSString *)modifiedDateStringOfFileAtUrl:(NSURL *)fileUrl -{ - if (fileUrl != nil) { - NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[fileUrl path] error:nil]; - NSDate *modifiedDate = [fileAttributes objectForKey:NSFileModificationDate]; - return [NSString stringWithFormat:@"%f", [modifiedDate timeIntervalSince1970]]; - } else { - return nil; - } -} - + (void)setDeploymentKey:(NSString *)deploymentKey { [CodePushConfig current].deploymentKey = deploymentKey; @@ -300,6 +286,20 @@ static NSString *bundleResourceName = @"main"; }); } +/* + * This returns the modified date as a string for a given file URL. + */ ++ (NSString *)modifiedDateStringOfFileAtURL:(NSURL *)fileURL +{ + if (fileURL != nil) { + NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[fileURL path] error:nil]; + NSDate *modifiedDate = [fileAttributes objectForKey:NSFileModificationDate]; + return [NSString stringWithFormat:@"%f", [modifiedDate timeIntervalSince1970]]; + } else { + return nil; + } +} + /* * This method is used when an update has failed installation * and the app needs to be rolled back to the previous bundle. From 038112edc96cbd3f4a4da51fb1247bc8a3cb8e4f Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Fri, 5 Feb 2016 17:46:16 -0800 Subject: [PATCH 16/16] add comment --- CodePush.m | 4 ++-- CodePushPackage.m | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CodePush.m b/CodePush.m index 09cec25..071b398 100644 --- a/CodePush.m +++ b/CodePush.m @@ -87,7 +87,7 @@ static NSString *bundleResourceName = @"main"; NSString *packageDate = [currentPackageMetadata objectForKey:BinaryBundleDateKey]; NSString *packageAppVersion = [currentPackageMetadata objectForKey:@"appVersion"]; - if ([[self modifiedDateStringOfFileAtUrl:binaryBundleURL] isEqualToString:packageDate] && ([CodePush isUsingTestConfiguration] ||[binaryAppVersion isEqualToString:packageAppVersion])) { + if ([[self modifiedDateStringOfFileAtURL:binaryBundleURL] isEqualToString:packageDate] && ([CodePush isUsingTestConfiguration] ||[binaryAppVersion isEqualToString:packageAppVersion])) { // Return package file because it is newer than the app store binary's JS bundle NSURL *packageUrl = [[NSURL alloc] initFileURLWithPath:packageFile]; NSLog(logMessageFormat, packageUrl); @@ -397,7 +397,7 @@ RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage NSDictionary *mutableUpdatePackage = [updatePackage mutableCopy]; NSURL *binaryBundleURL = [CodePush binaryBundleURL]; if (binaryBundleURL != nil) { - [mutableUpdatePackage setValue:[CodePush modifiedDateStringOfFileAtUrl:binaryBundleURL] + [mutableUpdatePackage setValue:[CodePush modifiedDateStringOfFileAtURL:binaryBundleURL] forKey:BinaryBundleDateKey]; } diff --git a/CodePushPackage.m b/CodePushPackage.m index 4d1300b..4a22430 100644 --- a/CodePushPackage.m +++ b/CodePushPackage.m @@ -229,6 +229,8 @@ NSString * const UnzippedFolderName = @"unzipped"; NSMutableDictionary * mutableUpdatePackage = [updatePackage mutableCopy]; if (isZip) { if ([[NSFileManager defaultManager] fileExistsAtPath:unzippedFolderPath]) { + // This removes any unzipped download data that could have been left + // uncleared due to a crash or error during the download process. [[NSFileManager defaultManager] removeItemAtPath:unzippedFolderPath error:&error]; if (error) {