mirror of
https://github.com/zhigang1992/react-native-code-push.git
synced 2026-05-19 19:39:54 +08:00
243 lines
7.9 KiB
Objective-C
243 lines
7.9 KiB
Objective-C
#import "CodePush.h"
|
|
|
|
@implementation CodePushPackage
|
|
|
|
NSString * const StatusFile = @"codepush.json";
|
|
NSString * const UpdateBundleFileName = @"app.jsbundle";
|
|
|
|
+ (NSString *)getCodePushPath
|
|
{
|
|
return [[CodePush getDocumentsDirectory] stringByAppendingPathComponent:@"CodePush"];
|
|
}
|
|
|
|
+ (NSString *)getStatusFilePath
|
|
{
|
|
return [[self getCodePushPath] stringByAppendingPathComponent:StatusFile];
|
|
}
|
|
|
|
+ (NSMutableDictionary *)getCurrentPackageInfo:(NSError **)error
|
|
{
|
|
NSString *statusFilePath = [self getStatusFilePath];
|
|
if (![[NSFileManager defaultManager] fileExistsAtPath:statusFilePath]) {
|
|
return [NSMutableDictionary dictionary];
|
|
}
|
|
|
|
NSString *content = [NSString stringWithContentsOfFile:statusFilePath
|
|
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 mutableCopy];
|
|
}
|
|
|
|
+ (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 getStatusFilePath]
|
|
atomically:YES
|
|
encoding:NSUTF8StringEncoding
|
|
error:error];
|
|
}
|
|
|
|
+ (NSString *)getCurrentPackageFolderPath:(NSError **)error
|
|
{
|
|
NSDictionary *info = [self getCurrentPackageInfo:error];
|
|
|
|
if (*error) {
|
|
return NULL;
|
|
}
|
|
|
|
NSString *packageHash = info[@"currentPackage"];
|
|
|
|
if (!packageHash) {
|
|
return NULL;
|
|
}
|
|
|
|
return [self getPackageFolderPath:packageHash];
|
|
}
|
|
|
|
+ (NSString *)getCurrentPackageBundlePath:(NSError **)error
|
|
{
|
|
NSString *packageFolder = [self getCurrentPackageFolderPath:error];
|
|
|
|
if(*error) {
|
|
return NULL;
|
|
}
|
|
|
|
return [packageFolder stringByAppendingPathComponent:UpdateBundleFileName];
|
|
}
|
|
|
|
+ (NSString *)getCurrentPackageHash:(NSError **)error
|
|
{
|
|
NSDictionary *info = [self getCurrentPackageInfo:error];
|
|
if (*error) {
|
|
return NULL;
|
|
}
|
|
|
|
return info[@"currentPackage"];
|
|
}
|
|
|
|
+ (NSString *)getPreviousPackageHash:(NSError **)error
|
|
{
|
|
NSDictionary *info = [self getCurrentPackageInfo:error];
|
|
if (*error) {
|
|
return NULL;
|
|
}
|
|
|
|
return info[@"previousPackage"];
|
|
}
|
|
|
|
+ (NSDictionary *)getCurrentPackage:(NSError **)error
|
|
{
|
|
NSString *folderPath = [CodePushPackage getCurrentPackageFolderPath:error];
|
|
if (!*error) {
|
|
if (!folderPath) {
|
|
return [NSDictionary dictionary];
|
|
}
|
|
|
|
NSString *packagePath = [folderPath stringByAppendingPathComponent:@"app.json"];
|
|
NSString *content = [NSString stringWithContentsOfFile:packagePath
|
|
encoding:NSUTF8StringEncoding
|
|
error:error];
|
|
if (!*error) {
|
|
NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
|
|
NSDictionary* jsonDict = [NSJSONSerialization JSONObjectWithData:data
|
|
options:kNilOptions
|
|
error:error];
|
|
|
|
return jsonDict;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
+ (NSDictionary *)getPackage:(NSString *)packageHash
|
|
error:(NSError **)error
|
|
{
|
|
NSString *folderPath = [self getPackageFolderPath:packageHash];
|
|
|
|
if (!folderPath) {
|
|
return [NSDictionary dictionary];
|
|
}
|
|
|
|
NSString *packageFilePath = [folderPath stringByAppendingPathComponent:@"app.json"];
|
|
|
|
NSString *content = [NSString stringWithContentsOfFile:packageFilePath
|
|
encoding:NSUTF8StringEncoding
|
|
error:error];
|
|
if (!*error) {
|
|
NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
|
|
NSDictionary* jsonDict = [NSJSONSerialization JSONObjectWithData:data
|
|
options:kNilOptions
|
|
error:error];
|
|
|
|
return jsonDict;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
+ (NSString *)getPackageFolderPath:(NSString *)packageHash
|
|
{
|
|
return [[self getCodePushPath] stringByAppendingPathComponent:packageHash];
|
|
}
|
|
|
|
+ (void)downloadPackage:(NSDictionary *)updatePackage
|
|
progressCallback:(void (^)(long, long))progressCallback
|
|
doneCallback:(void (^)())doneCallback
|
|
failCallback:(void (^)(NSError *err))failCallback
|
|
{
|
|
NSString *packageFolderPath = [self getPackageFolderPath:updatePackage[@"packageHash"]];
|
|
NSError *error = nil;
|
|
|
|
if (![[NSFileManager defaultManager] fileExistsAtPath:packageFolderPath]) {
|
|
[[NSFileManager defaultManager] createDirectoryAtPath:packageFolderPath
|
|
withIntermediateDirectories:YES
|
|
attributes:nil
|
|
error:&error];
|
|
}
|
|
|
|
if (error) {
|
|
return failCallback(error);
|
|
}
|
|
|
|
NSString *downloadFilePath = [packageFolderPath stringByAppendingPathComponent:UpdateBundleFileName];
|
|
|
|
CodePushDownloadHandler *downloadHandler = [[CodePushDownloadHandler alloc]
|
|
init:downloadFilePath
|
|
progressCallback:progressCallback
|
|
doneCallback:^{
|
|
NSError *error;
|
|
NSData *updateSerializedData = [NSJSONSerialization
|
|
dataWithJSONObject:updatePackage
|
|
options:0
|
|
error:&error];
|
|
NSString *packageJsonString = [[NSString alloc]
|
|
initWithData:updateSerializedData encoding:NSUTF8StringEncoding];
|
|
|
|
[packageJsonString writeToFile:[packageFolderPath stringByAppendingPathComponent:@"app.json"]
|
|
atomically:YES
|
|
encoding:NSUTF8StringEncoding
|
|
error:&error];
|
|
if (error) {
|
|
failCallback(error);
|
|
} else {
|
|
doneCallback();
|
|
}
|
|
}
|
|
failCallback:failCallback];
|
|
|
|
[downloadHandler download:updatePackage[@"downloadUrl"]];
|
|
}
|
|
|
|
+ (void)applyPackage:(NSDictionary *)updatePackage
|
|
error:(NSError **)error
|
|
{
|
|
NSString *packageHash = updatePackage[@"packageHash" ];
|
|
NSMutableDictionary *info = [self getCurrentPackageInfo:error];
|
|
|
|
if (*error) {
|
|
return;
|
|
}
|
|
|
|
[info setValue:info[@"currentPackage"] forKey:@"previousPackage"];
|
|
[info setValue:packageHash forKey:@"currentPackage"];
|
|
|
|
[self updateCurrentPackageInfo:info
|
|
error:error];
|
|
}
|
|
|
|
+ (void)rollbackPackage
|
|
{
|
|
NSError *error;
|
|
NSMutableDictionary *info = [self getCurrentPackageInfo:&error];
|
|
|
|
if (error) {
|
|
return;
|
|
}
|
|
|
|
[info setValue:info[@"previousPackage"] forKey:@"currentPackage"];
|
|
[info removeObjectForKey:@"previousPackage"];
|
|
|
|
[self updateCurrentPackageInfo:info error:&error];
|
|
}
|
|
|
|
@end |