Skip to content
This repository was archived by the owner on May 20, 2025. It is now read-only.

Commit 073cf5b

Browse files
author
Will Anderson
committed
Merge pull request #2 from Microsoft/check-update-and-download
Refactor plugin config, and change example so it can download updates
2 parents 70849c5 + b5b2788 commit 073cf5b

File tree

10 files changed

+226
-102
lines changed

10 files changed

+226
-102
lines changed

Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
4444
*
4545
* see http://facebook.github.io/react-native/docs/runningondevice.html
4646
*/
47-
48-
jsCodeLocation = [HybridMobileDeploy appBundleUrl];
47+
48+
jsCodeLocation = [HybridMobileDeploy getBundleUrl];
4949

5050
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
5151
moduleName:@"HybridMobileDeployCompanion"

Examples/HybridMobileDeployCompanion/iOS/Info.plist

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<key>CFBundlePackageType</key>
1616
<string>APPL</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>1.0</string>
18+
<string>1.2.3</string>
1919
<key>CFBundleSignature</key>
2020
<string>????</string>
2121
<key>CFBundleVersion</key>
@@ -38,5 +38,7 @@
3838
<false/>
3939
<key>NSLocationWhenInUseUsageDescription</key>
4040
<string></string>
41+
<key>CodePushDeploymentKey</key>
42+
<string>deployment-key-here</string>
4143
</dict>
4244
</plist>

Examples/HybridMobileDeployCompanion/index.ios.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var {
1515

1616
var Button = require("react-native-button");
1717

18-
var HybridMobileDeploy = require('react-native-hybrid-mobile-deploy')('http://localhost:3000/', '<deployment key here>');
18+
var HybridMobileDeploy = require('react-native-hybrid-mobile-deploy');
1919

2020
var HybridMobileDeployCompanion = React.createClass({
2121
componentDidMount: function() {
@@ -30,15 +30,15 @@ var HybridMobileDeployCompanion = React.createClass({
3030
return { update: false, updateString: "" };
3131
},
3232
handlePress: function() {
33-
console.log("pressed");
33+
HybridMobileDeploy.installUpdate(this.state.update);
3434
},
3535
render: function() {
3636
var updateView;
3737
if (this.state.update) {
3838
updateView = (
3939
<View>
4040
<Text>Update Available: {'\n'} {this.state.update.scriptVersion} - {this.state.update.description}</Text>
41-
<Button style={{color: 'green'}} onPress={this._handlePress}>
41+
<Button style={{color: 'green'}} onPress={this.handlePress}>
4242
Update
4343
</Button>
4444
</View>

Examples/HybridMobileDeployCompanion/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"start": "node_modules/react-native/packager/packager.sh --root ../../"
77
},
88
"dependencies": {
9-
"react-native": "^0.8.0-rc",
10-
"react-native-button": "^1.2.0"
9+
"react-native": "^0.8.0",
10+
"react-native-button": "^1.2.0",
11+
"react-native-hybrid-mobile-deploy": "file:../../"
1112
}
1213
}

HybridMobileDeploy.h

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,28 @@
11
#import "RCTBridgeModule.h"
22

33
@interface HybridMobileDeploy : NSObject <RCTBridgeModule>
4-
+ (NSString *) getBundlePath:(NSString*)bundleName;
5-
+ (NSURL *) getNativeBundleURL:(NSString*)bundleName;
6-
+ (NSURL *)appBundleUrl;
7-
+ (NSURL *)appBundleUrl:(NSString*)bundleName
8-
nativeBundleName:(NSString*)nativeBundleName;
4+
5+
+ (NSURL *) getBundleUrl;
6+
97
@end
8+
9+
@interface HybridMobileDeployConfig : NSObject
10+
11+
+ (void)setDeploymentKey:(NSString *)deploymentKey;
12+
+ (NSString *)getDeploymentKey;
13+
14+
+ (void)setServerUrl:(NSString *)setServerUrl;
15+
+ (NSString *)getServerUrl;
16+
17+
+ (void)setAppVersion:(NSString *)appVersion;
18+
+ (NSString *)getAppVersion;
19+
20+
+ (void)setBuildVersion:(NSString *)buildVersion;
21+
+ (NSString *)getBuildVersion;
22+
23+
+ (void)setRootComponent:(NSString *)rootComponent;
24+
+ (NSString *)getRootComponent;
25+
26+
+ (NSDictionary *)getConfiguration;
27+
28+
@end

HybridMobileDeploy.ios.js

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,58 @@
88
var NativeHybridMobileDeploy = require('react-native').NativeModules.HybridMobileDeploy;
99
var requestFetchAdapter = require("./request-fetch-adapter.js");
1010
var semver = require('semver');
11-
var Sdk = require("hybrid-mobile-deploy-sdk/script/acquisition-sdk");
12-
var serverUrl;
13-
var appName;
11+
var Sdk = require("hybrid-mobile-deploy-sdk/script/acquisition-sdk").AcquisitionManager;
1412
var sdk;
13+
var config;
1514

16-
var HybridMobileDeploy = {
17-
queryUpdate: function(cb) {
18-
var pkg = {nativeVersion: "1.2.3", scriptVersion: "1.2.0"};
19-
sdk.queryUpdateWithCurrentPackage(pkg, cb);
20-
},
21-
installUpdate: function(update) {
22-
NativeHybridMobileDeploy.installUpdateFromUrl(update.updateUrl, update.bundleName, (err) => console.log(err), () => console.log("success"));
15+
function getConfiguration(callback) {
16+
if (config) {
17+
setImmediate(function() {
18+
callback(/*error=*/ null, config);
19+
});
20+
} else {
21+
NativeHybridMobileDeploy.getConfiguration(function(err, configuration) {
22+
if (err) callback(err);
23+
config = configuration;
24+
callback(/*error=*/ null, config);
25+
});
2326
}
24-
};
27+
}
2528

26-
module.exports = function(serverUrl, deploymentKey, ignoreNativeVersion) {
27-
sdk = new Sdk(requestFetchAdapter, {
28-
serverUrl: serverUrl,
29-
deploymentKey: deploymentKey,
30-
ignoreNativeVersion: ignoreNativeVersion
29+
function getSdk(callback) {
30+
if (sdk) {
31+
setImmediate(function() {
32+
callback(/*error=*/ null, sdk);
33+
});
34+
} else {
35+
getConfiguration(function(err, configuration) {
36+
sdk = new Sdk(requestFetchAdapter, configuration);
37+
callback(/*error=*/ null, sdk);
38+
});
39+
}
40+
}
41+
42+
function queryUpdate(callback) {
43+
getConfiguration(function(err, configuration) {
44+
if (err) callback(err);
45+
getSdk(function(err, sdk) {
46+
if (err) callback(err);
47+
var pkg = {appVersion: configuration.appVersion};
48+
sdk.queryUpdateWithCurrentPackage(pkg, callback);
49+
});
3150
});
32-
return HybridMobileDeploy;
51+
}
52+
53+
function installUpdate(update) {
54+
getConfiguration(function(err, config) {
55+
NativeHybridMobileDeploy.installUpdateFromUrl(config.serverUrl + "acquire/" + config.deploymentKey, (err) => console.log(err));
56+
});
57+
}
58+
59+
var HybridMobileDeploy = {
60+
getConfiguration: getConfiguration,
61+
queryUpdate: queryUpdate,
62+
installUpdate: installUpdate
3363
};
64+
65+
module.exports = HybridMobileDeploy;

HybridMobileDeploy.m

Lines changed: 52 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,96 @@
11
#import "HybridMobileDeploy.h"
22

3+
#import "RCTBridgeModule.h"
34
#import "RCTRootView.h"
45
#import "RCTUtils.h"
56

67
@implementation HybridMobileDeploy
78

89
RCT_EXPORT_MODULE()
910

11+
RCTBridge * _bridge;
12+
13+
@synthesize bridge = _bridge;
14+
1015
+ (NSString *) getBundleFolderPath
1116
{
1217
NSString* home = NSHomeDirectory();
1318
NSString* bundleFolder = [home stringByAppendingPathComponent:@"HybridMobileDeploy"];
1419
return bundleFolder;
1520
}
1621

17-
+ (NSString *) getBundlePath:(NSString*)bundleName
22+
+ (NSString *) getBundlePath
1823
{
1924
NSString * bundleFolderPath = [self getBundleFolderPath];
20-
NSString* appBundleName = [bundleName stringByAppendingString:@".jsbundle"];
25+
NSString* appBundleName = @"main.jsbundle";
2126
return [bundleFolderPath stringByAppendingPathComponent:appBundleName];
2227
}
2328

24-
+ (NSURL *) getNativeBundleURL:(NSString*)bundleName
29+
+ (NSURL *) getNativeBundleURL
2530
{
26-
return [[NSBundle mainBundle] URLForResource:bundleName withExtension:@"jsbundle"];
31+
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
2732
}
2833

29-
+ (NSURL *) appBundleUrl
30-
{
31-
return [self appBundleUrl:@"bundle"
32-
nativeBundleName:@"main"];
33-
}
34-
35-
+ (NSURL *) appBundleUrl:(NSString*)bundleName
36-
nativeBundleName:(NSString*)nativeBundleName
34+
+ (NSURL *) getBundleUrl
3735
{
3836
NSFileManager *fileManager = [NSFileManager defaultManager];
3937

40-
NSString *bundlePath = [self getBundlePath:bundleName];
38+
NSString *bundlePath = [self getBundlePath];
4139
if ([fileManager fileExistsAtPath:bundlePath]) {
4240
return [[NSURL alloc] initFileURLWithPath:bundlePath];
4341
} else {
44-
return [self getNativeBundleURL:nativeBundleName];
42+
return [self getNativeBundleURL];
4543
}
4644
}
4745

48-
+ (void) loadBundle:(NSString*)moduleName
49-
nativeBundleName:(NSString*)nativeBundleName
46+
- (void) reloadBundle
5047
{
5148
dispatch_async(dispatch_get_main_queue(), ^{
52-
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:[self appBundleUrl:moduleName nativeBundleName:nativeBundleName]
53-
moduleName:moduleName
54-
launchOptions:nil];
55-
56-
UIViewController *rootViewController = [[UIViewController alloc] init];
57-
rootViewController.view = rootView;
58-
[UIApplication sharedApplication].delegate.window.rootViewController = rootViewController;
49+
self.bridge.bundleURL = [HybridMobileDeploy getBundleUrl];
50+
[self.bridge reload];
5951
});
6052
}
6153

62-
RCT_EXPORT_METHOD(installUpdateFromUrl:(NSString*)updateUrl
63-
bundleName:(NSString*)bundleName
64-
nativeBundleName:(NSString*)nativeBundleName
65-
failureCallback:(RCTResponseSenderBlock)failureCallback
66-
successCallback:(RCTResponseSenderBlock)successCallback)
54+
RCT_EXPORT_METHOD(getConfiguration:(RCTResponseSenderBlock)callback)
6755
{
68-
NSError *parameterError;
69-
NSMutableDictionary *errorData;
70-
if (!updateUrl) {
71-
errorData = [NSMutableDictionary dictionary];
72-
[errorData setValue:@"missing-updateUrl" forKey:NSLocalizedDescriptionKey];
73-
} else if (!bundleName) {
74-
errorData = [NSMutableDictionary dictionary];
75-
[errorData setValue:@"missing-bundleName" forKey:NSLocalizedDescriptionKey];
76-
}
56+
callback(@[[NSNull null], [HybridMobileDeployConfig getConfiguration]]);
57+
}
7758

78-
if (errorData) {
79-
parameterError = [NSError errorWithDomain:@"HybridMobileDeploy"code:200 userInfo:errorData];
80-
NSDictionary *rctError = RCTMakeError(@"Error with input to installUpdateFromUrl", parameterError, errorData);
81-
failureCallback(@[rctError]);
82-
} else {
83-
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
84-
NSURL* url = [NSURL URLWithString:updateUrl];
85-
NSError *err;
59+
RCT_EXPORT_METHOD(installUpdateFromUrl:(NSString*)updateUrl
60+
callback:(RCTResponseSenderBlock)callback)
61+
{
62+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
63+
NSURL* url = [NSURL URLWithString:updateUrl];
64+
NSError *err;
8665

87-
NSString *updateContents = [[NSString alloc] initWithContentsOfURL:url
88-
encoding:NSUTF8StringEncoding
89-
error:&err];
90-
if (err) {
91-
failureCallback(@[err]);
92-
} else {
93-
dispatch_async(dispatch_get_main_queue(), ^{
94-
NSError *saveError;
95-
NSString *bundleFolderPath = [HybridMobileDeploy getBundleFolderPath];
96-
if (![[NSFileManager defaultManager] fileExistsAtPath:bundleFolderPath]) {
97-
[[NSFileManager defaultManager] createDirectoryAtPath:bundleFolderPath withIntermediateDirectories:YES attributes:nil error:&saveError];
98-
}
99-
[updateContents writeToFile:[HybridMobileDeploy getBundlePath:bundleName]
100-
atomically:YES
101-
encoding:NSUTF8StringEncoding
102-
error:&saveError];
103-
if (saveError) {
104-
failureCallback(@[saveError]);
105-
} else {
106-
[HybridMobileDeploy loadBundle:bundleName nativeBundleName:nativeBundleName];
107-
successCallback(@[]);
108-
}
109-
});
110-
}
111-
});
112-
}
66+
NSString *updateContents = [[NSString alloc] initWithContentsOfURL:url
67+
encoding:NSUTF8StringEncoding
68+
error:&err];
69+
70+
if (err) {
71+
// TODO send download url
72+
callback(@[RCTMakeError(@"Error downloading url", err, [[NSDictionary alloc] initWithObjectsAndKeys:updateUrl,@"updateUrl", nil])]);
73+
} else {
74+
dispatch_async(dispatch_get_main_queue(), ^{
75+
NSError *saveError;
76+
NSString *bundleFolderPath = [HybridMobileDeploy getBundleFolderPath];
77+
if (![[NSFileManager defaultManager] fileExistsAtPath:bundleFolderPath]) {
78+
[[NSFileManager defaultManager] createDirectoryAtPath:bundleFolderPath withIntermediateDirectories:YES attributes:nil error:&saveError];
79+
}
80+
[updateContents writeToFile:[HybridMobileDeploy getBundlePath]
81+
atomically:YES
82+
encoding:NSUTF8StringEncoding
83+
error:&saveError];
84+
if (saveError) {
85+
// TODO send file path
86+
callback(@[RCTMakeError(@"Error saving file", err, [[NSDictionary alloc] initWithObjectsAndKeys:[HybridMobileDeploy getBundlePath],@"bundlePath", nil])]);
87+
} else {
88+
[self reloadBundle];
89+
callback(@[[NSNull null]]);
90+
}
91+
});
92+
}
93+
});
11394
}
11495

11596
@end

HybridMobileDeploy.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
/* Begin PBXBuildFile section */
1010
13BE3DEE1AC21097009241FE /* HybridMobileDeploy.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BE3DED1AC21097009241FE /* HybridMobileDeploy.m */; };
11+
81D51F3A1B6181C2000DA084 /* HybridMobileDeployConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 81D51F391B6181C2000DA084 /* HybridMobileDeployConfig.m */; };
1112
/* End PBXBuildFile section */
1213

1314
/* Begin PBXCopyFilesBuildPhase section */
@@ -26,6 +27,7 @@
2627
134814201AA4EA6300B7C361 /* libHybridMobileDeploy.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libHybridMobileDeploy.a; sourceTree = BUILT_PRODUCTS_DIR; };
2728
13BE3DEC1AC21097009241FE /* HybridMobileDeploy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HybridMobileDeploy.h; sourceTree = "<group>"; };
2829
13BE3DED1AC21097009241FE /* HybridMobileDeploy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HybridMobileDeploy.m; sourceTree = "<group>"; };
30+
81D51F391B6181C2000DA084 /* HybridMobileDeployConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HybridMobileDeployConfig.m; sourceTree = "<group>"; };
2931
/* End PBXFileReference section */
3032

3133
/* Begin PBXFrameworksBuildPhase section */
@@ -50,6 +52,7 @@
5052
58B511D21A9E6C8500147676 = {
5153
isa = PBXGroup;
5254
children = (
55+
81D51F391B6181C2000DA084 /* HybridMobileDeployConfig.m */,
5356
13BE3DEC1AC21097009241FE /* HybridMobileDeploy.h */,
5457
13BE3DED1AC21097009241FE /* HybridMobileDeploy.m */,
5558
134814211AA4EA7D00B7C361 /* Products */,
@@ -112,6 +115,7 @@
112115
isa = PBXSourcesBuildPhase;
113116
buildActionMask = 2147483647;
114117
files = (
118+
81D51F3A1B6181C2000DA084 /* HybridMobileDeployConfig.m in Sources */,
115119
13BE3DEE1AC21097009241FE /* HybridMobileDeploy.m in Sources */,
116120
);
117121
runOnlyForDeploymentPostprocessing = 0;

0 commit comments

Comments
 (0)