mirror of
https://github.com/zhigang1992/react-native-code-push.git
synced 2026-06-10 07:10:36 +08:00
Start refactoring package management into a distinct class
This commit is contained in:
13
CodePush.h
13
CodePush.h
@@ -25,4 +25,17 @@
|
||||
|
||||
+ (NSDictionary *)getConfiguration;
|
||||
|
||||
@end
|
||||
|
||||
@interface CodePushPackage : NSObject
|
||||
|
||||
+ (NSString *)getCurrentPackageFolderPath:(NSError **)error;
|
||||
|
||||
+ (NSString *)getPackageFolderPath:(NSString *)packageHash;
|
||||
|
||||
+ (void)downloadPackage:(NSDictionary *)updatePackage
|
||||
error:(NSError **)error;
|
||||
|
||||
+ (void)applyPackage:(NSString *)packageHash;
|
||||
|
||||
@end
|
||||
@@ -5,9 +5,11 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var extend = require("extend");
|
||||
var NativeCodePush = require('react-native').NativeModules.CodePush;
|
||||
var requestFetchAdapter = require("./request-fetch-adapter.js");
|
||||
var Sdk = require("code-push/script/acquisition-sdk").AcquisitionManager;
|
||||
var packageMixins = require("./package-mixins")(NativeCodePush);
|
||||
|
||||
// This function is only used for tests. Replaces the default SDK, configuration and native bridge
|
||||
function setUpTestDependencies(testSdk, testConfiguration, testNativeBridge){
|
||||
@@ -67,18 +69,12 @@ function checkForUpdate() {
|
||||
return new Promise((resolve, reject) => {
|
||||
sdk.queryUpdateWithCurrentPackage(queryPackage, (err, update) => {
|
||||
if (err) return reject(err);
|
||||
resolve(update);
|
||||
resolve(extend({}, update, packageMixins.remote));
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function download(updatePackage) {
|
||||
// Use the downloaded package info. Native code will save the package info
|
||||
// so that the client knows what the current package version is.
|
||||
return NativeCodePush.downloadUpdate(updatePackage);
|
||||
}
|
||||
|
||||
function apply(updatePackage) {
|
||||
return NativeCodePush.applyUpdate(updatePackage);
|
||||
}
|
||||
@@ -94,7 +90,6 @@ function notifyApplicationReady() {
|
||||
var CodePush = {
|
||||
getConfiguration: getConfiguration,
|
||||
checkForUpdate: checkForUpdate,
|
||||
download: download,
|
||||
apply: apply,
|
||||
getCurrentPackage: getCurrentPackage,
|
||||
notifyApplicationReady: notifyApplicationReady,
|
||||
|
||||
95
CodePush.m
95
CodePush.m
@@ -14,17 +14,9 @@ BOOL usingTestFolder = NO;
|
||||
|
||||
@synthesize bridge = _bridge;
|
||||
|
||||
+ (NSString *) getBundleFolderPath
|
||||
{
|
||||
NSString* home = NSHomeDirectory();
|
||||
NSString* pathExtension = [[@"CodePush/" stringByAppendingString: (usingTestFolder ? @"test/" : @"")] stringByAppendingString: @"bundle"];
|
||||
NSString* bundleFolder = [home stringByAppendingPathComponent:pathExtension];
|
||||
return bundleFolder;
|
||||
}
|
||||
|
||||
+ (NSString *) getBundlePath
|
||||
{
|
||||
NSString * bundleFolderPath = [self getBundleFolderPath];
|
||||
NSString * bundleFolderPath = [self getPackageFolderPath];
|
||||
NSString* appBundleName = @"main.jsbundle";
|
||||
return [bundleFolderPath stringByAppendingPathComponent:appBundleName];
|
||||
}
|
||||
@@ -32,14 +24,29 @@ BOOL usingTestFolder = NO;
|
||||
+ (NSString *) getPackageFolderPath
|
||||
{
|
||||
NSString* home = NSHomeDirectory();
|
||||
NSString* pathExtension = [[@"CodePush/" stringByAppendingString: (usingTestFolder ? @"test/" : @"")] stringByAppendingString: @"package"];
|
||||
NSString* pathExtension = [[@"CodePush/" stringByAppendingString: (usingTestFolder ? @"test/" : @"")] stringByAppendingString: @"currentPackage"];
|
||||
NSString* packageFolder = [home stringByAppendingPathComponent:pathExtension];
|
||||
return packageFolder;
|
||||
}
|
||||
|
||||
+ (NSString *) getPreviousPackageFolderPath
|
||||
{
|
||||
NSString* home = NSHomeDirectory();
|
||||
NSString* pathExtension = [[@"CodePush/" stringByAppendingString: (usingTestFolder ? @"test/" : @"")] stringByAppendingString: @"previous"];
|
||||
NSString* packageFolder = [home stringByAppendingPathComponent:pathExtension];
|
||||
return packageFolder;
|
||||
}
|
||||
|
||||
+ (NSString *) getPackagePath
|
||||
{
|
||||
NSString * packageFolderPath = [self getPackageFolderPath];
|
||||
NSString *packageFolderPath = [self getPackageFolderPath];
|
||||
NSString* appPackageName = @"localpackage.json";
|
||||
return [packageFolderPath stringByAppendingPathComponent:appPackageName];
|
||||
}
|
||||
|
||||
+ (NSString *) getPreviousPackagePath
|
||||
{
|
||||
NSString * packageFolderPath = [self getPreviousPackageFolderPath];
|
||||
NSString* appPackageName = @"localpackage.json";
|
||||
return [packageFolderPath stringByAppendingPathComponent:appPackageName];
|
||||
}
|
||||
@@ -86,67 +93,31 @@ RCT_EXPORT_METHOD(getConfiguration:(RCTPromiseResolveBlock)resolve
|
||||
resolve([CodePushConfig getConfiguration]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(installUpdate:(NSDictionary*)updatePackage
|
||||
RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
NSURL* url = [NSURL URLWithString:updatePackage[@"downloadUrl"]];
|
||||
NSError *err;
|
||||
|
||||
NSString *updateContents = [[NSString alloc] initWithContentsOfURL:url
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:&err];
|
||||
if (err) {
|
||||
// TODO send download url
|
||||
return reject(err);
|
||||
}
|
||||
[CodePushPackage downloadPackage:updatePackage
|
||||
error:&err];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSError *saveError;
|
||||
NSString *bundleFolderPath = [CodePush getBundleFolderPath];
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:bundleFolderPath]) {
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:bundleFolderPath withIntermediateDirectories:YES attributes:nil error:&saveError];
|
||||
}
|
||||
|
||||
[updateContents writeToFile:[CodePush getBundlePath]
|
||||
atomically:YES
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:&saveError];
|
||||
if (saveError) {
|
||||
// TODO send file path
|
||||
return reject(saveError);
|
||||
}
|
||||
|
||||
// Save the package info too.
|
||||
NSString *packageFolderPath = [CodePush getPackageFolderPath];
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:packageFolderPath]) {
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:packageFolderPath withIntermediateDirectories:YES attributes:nil error:&saveError];
|
||||
}
|
||||
|
||||
NSError *updateSerializeError;
|
||||
NSData *updateSerializedData = [NSJSONSerialization dataWithJSONObject:updatePackage options:0 error:&updateSerializeError];
|
||||
|
||||
if (updateSerializeError) {
|
||||
return reject(updateSerializeError);
|
||||
}
|
||||
|
||||
NSString *packageJsonString = [[NSString alloc] initWithData:updateSerializedData encoding:NSUTF8StringEncoding];
|
||||
[packageJsonString writeToFile:[CodePush getPackagePath]
|
||||
atomically:YES
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:&saveError];
|
||||
|
||||
if (saveError) {
|
||||
return reject(saveError);
|
||||
}
|
||||
|
||||
[CodePush loadBundle:[CodePushConfig getRootComponent]];
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve([NSNull null]);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(applyUpdate:(NSDictionary*)updatePackage
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
[CodePush loadBundle:[CodePushConfig getRootComponent]];
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(writeToLocalPackage:(NSString*)packageJsonString
|
||||
callback:(RCTResponseSenderBlock)callback)
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
13BE3DEE1AC21097009241FE /* CodePush.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BE3DED1AC21097009241FE /* CodePush.m */; };
|
||||
810D4E6D1B96935000B397E9 /* CodePushPackage.m in Sources */ = {isa = PBXBuildFile; fileRef = 810D4E6C1B96935000B397E9 /* CodePushPackage.m */; };
|
||||
81D51F3A1B6181C2000DA084 /* CodePushConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 81D51F391B6181C2000DA084 /* CodePushConfig.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -27,6 +28,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>"; };
|
||||
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>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@@ -52,6 +54,7 @@
|
||||
58B511D21A9E6C8500147676 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
810D4E6C1B96935000B397E9 /* CodePushPackage.m */,
|
||||
81D51F391B6181C2000DA084 /* CodePushConfig.m */,
|
||||
13BE3DEC1AC21097009241FE /* CodePush.h */,
|
||||
13BE3DED1AC21097009241FE /* CodePush.m */,
|
||||
@@ -117,6 +120,7 @@
|
||||
files = (
|
||||
81D51F3A1B6181C2000DA084 /* CodePushConfig.m in Sources */,
|
||||
13BE3DEE1AC21097009241FE /* CodePush.m in Sources */,
|
||||
810D4E6D1B96935000B397E9 /* CodePushPackage.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
131
CodePushPackage.m
Normal file
131
CodePushPackage.m
Normal file
@@ -0,0 +1,131 @@
|
||||
#import "CodePush.h"
|
||||
|
||||
@implementation CodePushPackage
|
||||
|
||||
NSString * const PackageInfoFile = @"packages.json";
|
||||
|
||||
+ (NSString *)getCodePushPath
|
||||
{
|
||||
return [NSHomeDirectory() stringByAppendingPathComponent:@"CodePush"];
|
||||
}
|
||||
|
||||
+ (NSString *)getCurrentPackageInfoPath
|
||||
{
|
||||
return [[self getCodePushPath] stringByAppendingPathComponent:PackageInfoFile];
|
||||
}
|
||||
|
||||
+ (NSDictionary *)getCurrentPackageInfo:(NSError **)error
|
||||
{
|
||||
NSString *content = [NSString stringWithContentsOfFile:[self getCurrentPackageInfoPath]
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:error];
|
||||
if (*error) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data
|
||||
options:kNilOptions
|
||||
error:error];
|
||||
if (*error) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
+ (void)updateCurrentPackageInfo:(NSDictionary *)packageInfo
|
||||
error:(NSError **)error
|
||||
{
|
||||
|
||||
NSData *packageInfoData = [NSJSONSerialization dataWithJSONObject:packageInfo
|
||||
options:0
|
||||
error:error];
|
||||
|
||||
NSString *packageInfoString = [[NSString alloc] initWithData:packageInfoData
|
||||
encoding:NSUTF8StringEncoding];
|
||||
[packageInfoString writeToFile:[self getCurrentPackageInfoPath]
|
||||
atomically:YES
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:error];
|
||||
}
|
||||
|
||||
+ (NSString *)getCurrentPackageFolderPath:(NSError **)error
|
||||
{
|
||||
NSDictionary *info = [self getCurrentPackageInfo:error];
|
||||
|
||||
if (*error) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return [self getPackageFolderPath:info[@"currentPackage"]];
|
||||
}
|
||||
|
||||
+ (NSString *)getPackageFolderPath:(NSString *)packageHash
|
||||
{
|
||||
return [[self getCodePushPath] stringByAppendingPathComponent:packageHash];
|
||||
}
|
||||
|
||||
+ (void)downloadPackage:(NSDictionary *)updatePackage
|
||||
error:(NSError **)error
|
||||
{
|
||||
NSString *packageFolderPath = [self getPackageFolderPath:updatePackage[@"packageHash"]];
|
||||
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:packageFolderPath]) {
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:packageFolderPath
|
||||
withIntermediateDirectories:YES
|
||||
attributes:nil
|
||||
error:error];
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSURL *url = [[NSURL alloc] initWithString:updatePackage[@"downloadUrl"]];
|
||||
NSString *updateContents = [[NSString alloc] initWithContentsOfURL:url
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:error];
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
[updateContents writeToFile:[packageFolderPath stringByAppendingPathComponent:@"app.jsbundle"]
|
||||
atomically:YES
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:error];
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSData *updateSerializedData = [NSJSONSerialization dataWithJSONObject:updatePackage
|
||||
options:0
|
||||
error:error];
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *packageJsonString = [[NSString alloc] initWithData:updateSerializedData encoding:NSUTF8StringEncoding];
|
||||
[packageJsonString writeToFile:[packageFolderPath stringByAppendingPathComponent:@"app.json"]
|
||||
atomically:YES
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:error];
|
||||
}
|
||||
|
||||
+ (void)applyPackage:(NSString *)packageHash
|
||||
error:(NSError **)error
|
||||
{
|
||||
NSDictionary *info = [self getCurrentPackageInfo:error];
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
[info setValue:packageHash forKey:@"currentPackage"];
|
||||
|
||||
[self updateCurrentPackageInfo:info
|
||||
error:error];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -30,7 +30,9 @@ var CodePushDemoApp = React.createClass({
|
||||
return { update: false };
|
||||
},
|
||||
handlePress: function() {
|
||||
CodePush.installUpdate(this.state.update).done();
|
||||
this.state.update.download((localPackage) => {
|
||||
localPackage.apply().done();
|
||||
});
|
||||
},
|
||||
render: function() {
|
||||
var updateView;
|
||||
|
||||
Reference in New Issue
Block a user