From 0420caa93fc3ae435882ed3129a6bf556d396619 Mon Sep 17 00:00:00 2001 From: Jonathan Carter Date: Tue, 26 Jan 2016 15:33:10 -0800 Subject: [PATCH] Exposing deploymentKey to CodePush --- CodePush.h | 11 ++++- CodePush.m | 129 ++++++++++++++++++++++++++++------------------------- 2 files changed, 77 insertions(+), 63 deletions(-) diff --git a/CodePush.h b/CodePush.h index 428c81b..af37f22 100644 --- a/CodePush.h +++ b/CodePush.h @@ -12,7 +12,7 @@ * This method assumes that your JS bundle is named "main.jsbundle" * and therefore, if it isn't, you should use either the bundleURLForResource: * or bundleURLForResource:withExtension: methods to override that behavior. -*/ + */ + (NSURL *)bundleURL; + (NSURL *)bundleURLForResource:(NSString *)resourceName; @@ -22,6 +22,13 @@ + (NSString *)getApplicationSupportDirectory; +/* + * This methods allows dynamically setting the app's + * deployment key, in addition to setting it via + * the Info.plist file's CodePushDeploymentKey setting. + */ ++ (void)setDeploymentKey:(NSString *)deploymentKey; + // The below methods are only used during tests. + (BOOL)isUsingTestConfiguration; + (void)setUsingTestConfiguration:(BOOL)shouldUseTestConfiguration; @@ -62,7 +69,7 @@ failCallback:(void (^)(NSError *err))failCallback; @interface CodePushPackage : NSObject + (void)installPackage:(NSDictionary *)updatePackage - error:(NSError **)error; + error:(NSError **)error; + (NSDictionary *)getCurrentPackage:(NSError **)error; + (NSString *)getCurrentPackageFolderPath:(NSError **)error; diff --git a/CodePush.m b/CodePush.m index 3b69041..6fbf0b6 100644 --- a/CodePush.m +++ b/CodePush.m @@ -13,6 +13,8 @@ RCT_EXPORT_MODULE() +#pragma mark - Private constants + static BOOL needToReportRollback = NO; static BOOL isRunningBinaryVersion = NO; static BOOL testConfigurationFlag = NO; @@ -38,9 +40,8 @@ static NSString *const LabelKey = @"label"; static NSString *const PackageHashKey = @"packageHash"; static NSString *const PackageIsPendingKey = @"isPending"; -@synthesize bridge = _bridge; +#pragma mark - Public Obj-C API -// Public Obj-C API (see header for method comments) + (NSURL *)bundleURL { return [self bundleURLForResource:@"main"]; @@ -91,7 +92,7 @@ static NSString *const PackageIsPendingKey = @"isPending"; #ifndef DEBUG [CodePush clearUpdates]; #endif - + NSLog(logMessageFormat, binaryJsBundleUrl); isRunningBinaryVersion = YES; return binaryJsBundleUrl; @@ -113,7 +114,12 @@ static NSString *const PackageIsPendingKey = @"isPending"; return testConfigurationFlag; } -/* ++ (void)setDeploymentKey:(NSString *)deploymentKey +{ + [CodePushConfig current].deploymentKey = deploymentKey; +} + +/* * This is used to enable an environment in which tests can be run. * Specifically, it flips a boolean flag that causes bundles to be * saved to a test folder and enables the ability to modify @@ -134,8 +140,9 @@ static NSString *const PackageIsPendingKey = @"isPending"; [self removeFailedUpdates]; } +#pragma mark - Private API methods -// Private API methods +@synthesize bridge = _bridge; /* * This method is used by the React Native bridge to allow @@ -147,11 +154,11 @@ static NSString *const PackageIsPendingKey = @"isPending"; { // Export the values of the CodePushInstallMode enum // so that the script-side can easily stay in sync - return @{ - @"codePushInstallModeOnNextRestart":@(CodePushInstallModeOnNextRestart), - @"codePushInstallModeImmediate": @(CodePushInstallModeImmediate), - @"codePushInstallModeOnNextResume": @(CodePushInstallModeOnNextResume) - }; + return @{ + @"codePushInstallModeOnNextRestart":@(CodePushInstallModeOnNextRestart), + @"codePushInstallModeImmediate": @(CodePushInstallModeImmediate), + @"codePushInstallModeOnNextResume": @(CodePushInstallModeOnNextResume) + }; }; - (void)dealloc @@ -257,12 +264,12 @@ static NSString *const PackageIsPendingKey = @"isPending"; { NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; NSDictionary *pendingUpdate = [preferences objectForKey:PendingUpdateKey]; - + // If there is a pending update whose "state" isn't loading, then we consider it "pending". // Additionally, if a specific hash was provided, we ensure it matches that of the pending update. BOOL updateIsPending = pendingUpdate && - [pendingUpdate[PendingUpdateIsLoadingKey] boolValue] == NO && - (!packageHash || [pendingUpdate[PendingUpdateHashKey] isEqualToString:packageHash]); + [pendingUpdate[PendingUpdateIsLoadingKey] boolValue] == NO && + (!packageHash || [pendingUpdate[PendingUpdateHashKey] isEqualToString:packageHash]); return updateIsPending; } @@ -380,41 +387,41 @@ static NSString *const PackageIsPendingKey = @"isPending"; [preferences synchronize]; } -// JavaScript-exported module methods +#pragma mark - JavaScript-exported module methods /* * This is native-side of the RemotePackage.download method */ RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { [CodePushPackage downloadPackage:updatePackage - // The download is progressing forward - progressCallback:^(long long expectedContentLength, long long receivedContentLength) { - // Notify the script-side about the progress - [self.bridge.eventDispatcher - sendDeviceEventWithName:@"CodePushDownloadProgress" - body:@{ - @"totalBytes":[NSNumber numberWithLongLong:expectedContentLength], - @"receivedBytes":[NSNumber numberWithLongLong:receivedContentLength] - }]; - } - // The download completed - doneCallback:^{ - NSError *err; - NSDictionary *newPackage = [CodePushPackage getPackage:updatePackage[PackageHashKey] error:&err]; - - if (err) { - return reject(err); - } - - resolve(newPackage); - } - // The download failed - failCallback:^(NSError *err) { - reject(err); - }]; + // The download is progressing forward + progressCallback:^(long long expectedContentLength, long long receivedContentLength) { + // Notify the script-side about the progress + [self.bridge.eventDispatcher + sendDeviceEventWithName:@"CodePushDownloadProgress" + body:@{ + @"totalBytes":[NSNumber numberWithLongLong:expectedContentLength], + @"receivedBytes":[NSNumber numberWithLongLong:receivedContentLength] + }]; + } + // The download completed + doneCallback:^{ + NSError *err; + NSDictionary *newPackage = [CodePushPackage getPackage:updatePackage[PackageHashKey] error:&err]; + + if (err) { + return reject(@"",@"",err); + } + + resolve(newPackage); + } + // The download failed + failCallback:^(NSError *err) { + reject(@"",@"",err); + }]; } /* @@ -424,7 +431,7 @@ RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage * app version, as well as the deployment key that was configured in the Info.plist file. */ RCT_EXPORT_METHOD(getConfiguration:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) + rejecter:(RCTPromiseRejectBlock)reject) { resolve([[CodePushConfig current] configuration]); } @@ -433,21 +440,21 @@ RCT_EXPORT_METHOD(getConfiguration:(RCTPromiseResolveBlock)resolve * This method is the native side of the CodePush.getCurrentPackage method. */ RCT_EXPORT_METHOD(getCurrentPackage:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) + rejecter:(RCTPromiseRejectBlock)reject) { dispatch_async(dispatch_get_main_queue(), ^{ NSError *error; NSMutableDictionary *package = [[CodePushPackage getCurrentPackage:&error] mutableCopy]; if (error) { - reject(error); + reject(@"",@"",error); } // Add the "isPending" virtual property to the package at this point, so that // the script-side doesn't need to immediately call back into native to populate it. BOOL isPendingUpdate = [self isPendingUpdate:[package objectForKey:PackageHashKey]]; [package setObject:@(isPendingUpdate) forKey:PackageIsPendingKey]; - + resolve(package); }); } @@ -456,9 +463,9 @@ RCT_EXPORT_METHOD(getCurrentPackage:(RCTPromiseResolveBlock)resolve * This method is the native side of the LocalPackage.install method. */ RCT_EXPORT_METHOD(installUpdate:(NSDictionary*)updatePackage - installMode:(CodePushInstallMode)installMode - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) + installMode:(CodePushInstallMode)installMode + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSError *error; @@ -466,7 +473,7 @@ RCT_EXPORT_METHOD(installUpdate:(NSDictionary*)updatePackage error:&error]; if (error) { - reject(error); + reject(@"",@"",error); } else { [self savePendingUpdate:updatePackage[PackageHashKey] isLoading:NO]; @@ -492,8 +499,8 @@ RCT_EXPORT_METHOD(installUpdate:(NSDictionary*)updatePackage * module, and is only used internally to populate the RemotePackage.failedInstall property. */ 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)); @@ -504,14 +511,14 @@ RCT_EXPORT_METHOD(isFailedUpdate:(NSString *)packageHash * module, and is only used internally to populate the LocalPackage.isFirstRun property. */ RCT_EXPORT_METHOD(isFirstRun:(NSString *)packageHash - resolve:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) + resolve:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { NSError *error; BOOL isFirstRun = _isFirstRunAfterUpdate - && nil != packageHash - && [packageHash length] > 0 - && [packageHash isEqualToString:[CodePushPackage getCurrentPackageHash:&error]]; + && nil != packageHash + && [packageHash length] > 0 + && [packageHash isEqualToString:[CodePushPackage getCurrentPackageHash:&error]]; resolve(@(isFirstRun)); } @@ -520,18 +527,18 @@ RCT_EXPORT_METHOD(isFirstRun:(NSString *)packageHash * This method is the native side of the CodePush.notifyApplicationReady() method. */ RCT_EXPORT_METHOD(notifyApplicationReady:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) + rejecter:(RCTPromiseRejectBlock)reject) { [CodePush removePendingUpdate]; resolve([NSNull null]); } /* - * This method is checks if a new status update exists (new version was installed, + * This method is checks if a new status update exists (new version was installed, * or an update failed) and return its details (version label, status). */ RCT_EXPORT_METHOD(getNewStatusReport:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) + rejecter:(RCTPromiseRejectBlock)reject) { if (needToReportRollback) { // Check if there was a rollback that was not yet reported @@ -589,7 +596,7 @@ RCT_EXPORT_METHOD(restartApp:(BOOL)onlyIfUpdateIsPending) /* * This method is the native side of the CodePush.downloadAndReplaceCurrentBundle() * method, which replaces the current bundle with the one downloaded from - * removeBundleUrl. It is only to be used during tests and no-ops if the test + * removeBundleUrl. It is only to be used during tests and no-ops if the test * configuration flag is not set. */ RCT_EXPORT_METHOD(downloadAndReplaceCurrentBundle:(NSString *)remoteBundleUrl) @@ -599,4 +606,4 @@ RCT_EXPORT_METHOD(downloadAndReplaceCurrentBundle:(NSString *)remoteBundleUrl) } } -@end +@end \ No newline at end of file