diff --git a/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m b/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m index 67cdc4d..4329c80 100644 --- a/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m +++ b/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m @@ -33,7 +33,7 @@ * on the same Wi-Fi network. */ - //jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"]; + jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"]; /** * OPTION 2 @@ -44,8 +44,8 @@ * * see http://facebook.github.io/react-native/docs/runningondevice.html */ - - jsCodeLocation = [HybridMobileDeploy appBundleUrl]; + + //jsCodeLocation = [HybridMobileDeploy getBundleUrl]; RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"HybridMobileDeployCompanion" diff --git a/Examples/HybridMobileDeployCompanion/iOS/Info.plist b/Examples/HybridMobileDeployCompanion/iOS/Info.plist index 0a56a6e..36b1aa4 100644 --- a/Examples/HybridMobileDeployCompanion/iOS/Info.plist +++ b/Examples/HybridMobileDeployCompanion/iOS/Info.plist @@ -38,5 +38,7 @@ NSLocationWhenInUseUsageDescription + CodePushDeploymentKey + deployment-key-here diff --git a/Examples/HybridMobileDeployCompanion/index.ios.js b/Examples/HybridMobileDeployCompanion/index.ios.js index 531050c..49ad592 100644 --- a/Examples/HybridMobileDeployCompanion/index.ios.js +++ b/Examples/HybridMobileDeployCompanion/index.ios.js @@ -15,7 +15,7 @@ var { var Button = require("react-native-button"); -var HybridMobileDeploy = require('react-native-hybrid-mobile-deploy')('http://localhost:3000/', ''); +var HybridMobileDeploy = require('react-native-hybrid-mobile-deploy'); var HybridMobileDeployCompanion = React.createClass({ componentDidMount: function() { diff --git a/HybridMobileDeploy.h b/HybridMobileDeploy.h index 417e23e..e043d24 100644 --- a/HybridMobileDeploy.h +++ b/HybridMobileDeploy.h @@ -1,9 +1,28 @@ #import "RCTBridgeModule.h" @interface HybridMobileDeploy : NSObject -+ (NSString *) getBundlePath:(NSString*)bundleName; -+ (NSURL *) getNativeBundleURL:(NSString*)bundleName; -+ (NSURL *)appBundleUrl; -+ (NSURL *)appBundleUrl:(NSString*)bundleName - nativeBundleName:(NSString*)nativeBundleName; + ++ (NSURL *) getBundleUrl; + @end + +@interface HybridMobileDeployConfig : NSObject + ++ (void)setDeploymentKey:(NSString *)deploymentKey; ++ (NSString *)getDeploymentKey; + ++ (void)setBaseUrl:(NSString *)baseUrl; ++ (NSString *)getBaseUrl; + ++ (void)setVersionString:(NSString *)baseUrl; ++ (NSString *)getVersionString; + ++ (void)setBuildVersion:(NSString *)buildVersion; ++ (NSString *)getBuildVersion; + ++ (void)setRootComponent:(NSString *)rootComponent; ++ (NSString *)getRootComponent; + ++ (NSDictionary *)getConfiguration; + +@end \ No newline at end of file diff --git a/HybridMobileDeploy.ios.js b/HybridMobileDeploy.ios.js index 70d1676..c77afde 100644 --- a/HybridMobileDeploy.ios.js +++ b/HybridMobileDeploy.ios.js @@ -9,25 +9,53 @@ var NativeHybridMobileDeploy = require('react-native').NativeModules.HybridMobil var requestFetchAdapter = require("./request-fetch-adapter.js"); var semver = require('semver'); var Sdk = require("hybrid-mobile-deploy-sdk/script/acquisition-sdk").AcquisitionManager; -var serverUrl; -var appName; var sdk; +var config; + +function getConfiguration(cb) { + if (config) { + setTimeout(function() { + cb(null, config); + }); + } else { + NativeHybridMobileDeploy.getConfiguration(function(err, configuration) { + if (err) cb(err); + config = configuration; + cb(null, config); + }); + } +} + +function getSdk(cb) { + if (sdk) { + setTimeout(function() { + cb(null, sdk); + }); + } else { + getConfiguration(function(err, configuration) { + sdk = new Sdk(requestFetchAdapter, configuration); + cb(null, sdk); + }); + } +} + +function queryUpdate(cb) { + getSdk(function(err, sdk) { + var pkg = {appVersion: "1.2.3"}; + sdk.queryUpdateWithCurrentPackage(pkg, cb); + }); +} + +function installUpdate(update) { + getConfiguration(function(err, config) { + NativeHybridMobileDeploy.installUpdateFromUrl(config.serverUrl + "acquire/" + config.deploymentKey, (err) => console.log(err)); + }); +} var HybridMobileDeploy = { - queryUpdate: function(cb) { - var pkg = {nativeVersion: "1.2.3", scriptVersion: "1.2.0"}; - sdk.queryUpdateWithCurrentPackage(pkg, cb); - }, - installUpdate: function(update) { - NativeHybridMobileDeploy.installUpdateFromUrl(update.updateUrl, update.bundleName, (err) => console.log(err), () => console.log("success")); - } + getConfiguration: getConfiguration, + queryUpdate: queryUpdate, + installUpdate: installUpdate }; -module.exports = function(serverUrl, deploymentKey, ignoreNativeVersion) { - sdk = new Sdk(requestFetchAdapter, { - serverUrl: serverUrl, - deploymentKey: deploymentKey, - ignoreNativeVersion: ignoreNativeVersion - }); - return HybridMobileDeploy; -}; +module.exports = HybridMobileDeploy; diff --git a/HybridMobileDeploy.m b/HybridMobileDeploy.m index 905eee0..52c9e83 100644 --- a/HybridMobileDeploy.m +++ b/HybridMobileDeploy.m @@ -14,43 +14,35 @@ RCT_EXPORT_MODULE() return bundleFolder; } -+ (NSString *) getBundlePath:(NSString*)bundleName ++ (NSString *) getBundlePath { NSString * bundleFolderPath = [self getBundleFolderPath]; - NSString* appBundleName = [bundleName stringByAppendingString:@".jsbundle"]; + NSString* appBundleName = @"main.jsbundle"; return [bundleFolderPath stringByAppendingPathComponent:appBundleName]; } -+ (NSURL *) getNativeBundleURL:(NSString*)bundleName ++ (NSURL *) getNativeBundleURL { - return [[NSBundle mainBundle] URLForResource:bundleName withExtension:@"jsbundle"]; + return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; } -+ (NSURL *) appBundleUrl -{ - return [self appBundleUrl:@"bundle" - nativeBundleName:@"main"]; -} - -+ (NSURL *) appBundleUrl:(NSString*)bundleName - nativeBundleName:(NSString*)nativeBundleName ++ (NSURL *) getBundleUrl { NSFileManager *fileManager = [NSFileManager defaultManager]; - NSString *bundlePath = [self getBundlePath:bundleName]; + NSString *bundlePath = [self getBundlePath]; if ([fileManager fileExistsAtPath:bundlePath]) { return [[NSURL alloc] initFileURLWithPath:bundlePath]; } else { - return [self getNativeBundleURL:nativeBundleName]; + return [self getNativeBundleURL]; } } -+ (void) loadBundle:(NSString*)moduleName - nativeBundleName:(NSString*)nativeBundleName ++ (void) loadBundle:(NSString*)rootComponent { dispatch_async(dispatch_get_main_queue(), ^{ - RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:[self appBundleUrl:moduleName nativeBundleName:nativeBundleName] - moduleName:moduleName + RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:[self getBundleUrl] + moduleName:rootComponent launchOptions:nil]; UIViewController *rootViewController = [[UIViewController alloc] init]; @@ -59,57 +51,46 @@ RCT_EXPORT_MODULE() }); } -RCT_EXPORT_METHOD(installUpdateFromUrl:(NSString*)updateUrl - bundleName:(NSString*)bundleName - nativeBundleName:(NSString*)nativeBundleName - failureCallback:(RCTResponseSenderBlock)failureCallback - successCallback:(RCTResponseSenderBlock)successCallback) +RCT_EXPORT_METHOD(getConfiguration:(RCTResponseSenderBlock)callback) { - NSError *parameterError; - NSMutableDictionary *errorData; - if (!updateUrl) { - errorData = [NSMutableDictionary dictionary]; - [errorData setValue:@"missing-updateUrl" forKey:NSLocalizedDescriptionKey]; - } else if (!bundleName) { - errorData = [NSMutableDictionary dictionary]; - [errorData setValue:@"missing-bundleName" forKey:NSLocalizedDescriptionKey]; - } + callback(@[[NSNull null], [HybridMobileDeployConfig getConfiguration]]); +} - if (errorData) { - parameterError = [NSError errorWithDomain:@"HybridMobileDeploy"code:200 userInfo:errorData]; - NSDictionary *rctError = RCTMakeError(@"Error with input to installUpdateFromUrl", parameterError, errorData); - failureCallback(@[rctError]); - } else { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - NSURL* url = [NSURL URLWithString:updateUrl]; - NSError *err; +RCT_EXPORT_METHOD(installUpdateFromUrl:(NSString*)updateUrl + callback:(RCTResponseSenderBlock)callback) +{ + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSURL* url = [NSURL URLWithString:updateUrl]; + NSError *err; - NSString *updateContents = [[NSString alloc] initWithContentsOfURL:url - encoding:NSUTF8StringEncoding - error:&err]; - if (err) { - failureCallback(@[err]); - } else { - dispatch_async(dispatch_get_main_queue(), ^{ - NSError *saveError; - NSString *bundleFolderPath = [HybridMobileDeploy getBundleFolderPath]; - if (![[NSFileManager defaultManager] fileExistsAtPath:bundleFolderPath]) { - [[NSFileManager defaultManager] createDirectoryAtPath:bundleFolderPath withIntermediateDirectories:YES attributes:nil error:&saveError]; - } - [updateContents writeToFile:[HybridMobileDeploy getBundlePath:bundleName] - atomically:YES - encoding:NSUTF8StringEncoding - error:&saveError]; - if (saveError) { - failureCallback(@[saveError]); - } else { - [HybridMobileDeploy loadBundle:bundleName nativeBundleName:nativeBundleName]; - successCallback(@[]); - } - }); - } - }); - } + NSString *updateContents = [[NSString alloc] initWithContentsOfURL:url + encoding:NSUTF8StringEncoding + error:&err]; + + if (err) { + // TODO send download url + callback(@[RCTMakeError(@"Error downloading url", err, [[NSDictionary alloc] initWithObjectsAndKeys:updateUrl,@"updateUrl", nil])]); + } else { + dispatch_async(dispatch_get_main_queue(), ^{ + NSError *saveError; + NSString *bundleFolderPath = [HybridMobileDeploy getBundleFolderPath]; + if (![[NSFileManager defaultManager] fileExistsAtPath:bundleFolderPath]) { + [[NSFileManager defaultManager] createDirectoryAtPath:bundleFolderPath withIntermediateDirectories:YES attributes:nil error:&saveError]; + } + [updateContents writeToFile:[HybridMobileDeploy getBundlePath] + atomically:YES + encoding:NSUTF8StringEncoding + error:&saveError]; + if (saveError) { + // TODO send file path + callback(@[RCTMakeError(@"Error saving file", err, [[NSDictionary alloc] initWithObjectsAndKeys:[HybridMobileDeploy getBundlePath],@"bundlePath", nil])]); + } else { + [HybridMobileDeploy loadBundle:[HybridMobileDeployConfig getRootComponent]]; + callback(@[[NSNull null]]); + } + }); + } + }); } @end diff --git a/HybridMobileDeploy.xcodeproj/project.pbxproj b/HybridMobileDeploy.xcodeproj/project.pbxproj index 170a646..fa8c150 100644 --- a/HybridMobileDeploy.xcodeproj/project.pbxproj +++ b/HybridMobileDeploy.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 13BE3DEE1AC21097009241FE /* HybridMobileDeploy.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BE3DED1AC21097009241FE /* HybridMobileDeploy.m */; }; + 81D51F3A1B6181C2000DA084 /* HybridMobileDeployConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 81D51F391B6181C2000DA084 /* HybridMobileDeployConfig.m */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -26,6 +27,7 @@ 134814201AA4EA6300B7C361 /* libHybridMobileDeploy.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libHybridMobileDeploy.a; sourceTree = BUILT_PRODUCTS_DIR; }; 13BE3DEC1AC21097009241FE /* HybridMobileDeploy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HybridMobileDeploy.h; sourceTree = ""; }; 13BE3DED1AC21097009241FE /* HybridMobileDeploy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HybridMobileDeploy.m; sourceTree = ""; }; + 81D51F391B6181C2000DA084 /* HybridMobileDeployConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HybridMobileDeployConfig.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -50,6 +52,7 @@ 58B511D21A9E6C8500147676 = { isa = PBXGroup; children = ( + 81D51F391B6181C2000DA084 /* HybridMobileDeployConfig.m */, 13BE3DEC1AC21097009241FE /* HybridMobileDeploy.h */, 13BE3DED1AC21097009241FE /* HybridMobileDeploy.m */, 134814211AA4EA7D00B7C361 /* Products */, @@ -112,6 +115,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 81D51F3A1B6181C2000DA084 /* HybridMobileDeployConfig.m in Sources */, 13BE3DEE1AC21097009241FE /* HybridMobileDeploy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/HybridMobileDeployConfig.m b/HybridMobileDeployConfig.m new file mode 100644 index 0000000..c8e9040 --- /dev/null +++ b/HybridMobileDeployConfig.m @@ -0,0 +1,85 @@ +#import "HybridMobileDeploy.h" + +NSMutableDictionary *configuration; + +@implementation HybridMobileDeployConfig + ++ (void)initialize +{ + NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; + + NSString *version = [infoDictionary objectForKey:@"CFBundleShortVersionString"]; + NSString *buildVersion = [infoDictionary objectForKey:@"CFBundleVersion"]; + NSString *deploymentKey = [infoDictionary objectForKey:@"CodePushDeploymentKey"]; + NSString *serverUrl = [infoDictionary objectForKey:@"CodePushServerUrl"]; + if (!serverUrl) { + serverUrl = @"http://localhost:3000/"; + } + NSString *rootComponent = [infoDictionary objectForKey:@"CFBundleName"]; + + configuration = [[NSMutableDictionary alloc] + initWithObjectsAndKeys: + version,@"versionString", + buildVersion,@"buildVersion", + deploymentKey,@"deploymentKey", + serverUrl,@"serverUrl", + rootComponent,@"rootComponent", + nil]; +} + ++ (void)setDeploymentKey:(NSString *)deploymentKey +{ + [configuration setValue:deploymentKey forKey:@"deploymentKey"]; +} + ++ (NSString *)getDeploymentKey +{ + return [configuration objectForKey:@"deploymentKey"]; +} + ++ (void)setServerUrl:(NSString *)serverUrl +{ + [configuration setValue:serverUrl forKey:@"serverUrl"]; +} + ++ (NSString *)getServerUrl +{ + return [configuration objectForKey:@"serverUrl"]; +} + ++ (void)setVersionString:(NSString *)baseUrl +{ + [configuration setValue:baseUrl forKey:@"versionString"]; +} + ++ (NSString *)getVersionString +{ + return [configuration objectForKey:@"versionString"]; +} + ++ (void)setBuildVersion:(NSString *)buildVersion +{ + [configuration setValue:buildVersion forKey:@"buildVersion"]; +} + ++ (NSString *)getBuildVersion +{ + return [configuration objectForKey:@"buildVersion"]; +} + ++ (void)setRootComponent:(NSString *)buildVersion +{ + [configuration setValue:buildVersion forKey:@"rootComponent"]; +} + ++ (NSString *)getRootComponent +{ + return [configuration objectForKey:@"rootComponent"]; +} + ++ (NSDictionary *) getConfiguration +{ + return configuration; +} + +@end \ No newline at end of file