Skip to content

Commit cad7906

Browse files
authored
Merge pull request #4 from xuwening/master
重新添加ios增量更新工程
2 parents ed62701 + fe9e937 commit cad7906

48 files changed

Lines changed: 12140 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ios/LDRNDiffUpdate.xcodeproj/project.pbxproj

Lines changed: 432 additions & 0 deletions
Large diffs are not rendered by default.

ios/LDRNDiffUpdate.xcodeproj/project.xcworkspace/contents.xcworkspacedata

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//
2+
// PatchFileManager.h
3+
// demo
4+
//
5+
// Created by hong on 2017/8/20.
6+
// Copyright © 2017年 leadeon. All rights reserved.
7+
//
8+
9+
#import <Foundation/Foundation.h>
10+
11+
@interface LDPatchFileManager : NSObject
12+
13+
+ (void) clearLDReactNativeCache;
14+
15+
+ (void) updateReactNativeLocalPath;
16+
+ (void) copyLDBundleToReactNativePath;
17+
+ (void) downloadPatchFile: (NSString *) url withBundle: (NSString *) bundleName;
18+
+ (void) reloadAllJSPatch;
19+
20+
+ (NSString *) jsbundleLocation: (NSString *) bundleName;
21+
22+
23+
@end
Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
//
2+
// PatchFileManager.m
3+
// demo
4+
//
5+
// Created by hong on 2017/8/20.
6+
// Copyright © 2017年 leadeon. All rights reserved.
7+
//
8+
9+
#import "LDPatchFileManager.h"
10+
#import "LDRNBundleList.h"
11+
#import "SSZipArchive.h"
12+
#import "bspatch.h"
13+
#import "FileHash.h"
14+
15+
@implementation LDPatchFileManager
16+
17+
18+
+ (NSString *)getApplicationSupportDirectory
19+
{
20+
NSString *applicationSupportDirectory = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) objectAtIndex:0];
21+
return applicationSupportDirectory;
22+
}
23+
24+
+ (NSString *) getLDReactNativePath {
25+
26+
return [[LDPatchFileManager getApplicationSupportDirectory] stringByAppendingPathComponent: [LDRNBundleList LDRNRootpath]];
27+
}
28+
29+
+ (void) clearLDReactNativeCache {
30+
31+
NSString *rnPath = [LDPatchFileManager getLDReactNativePath];
32+
[LDPatchFileManager clearFilesForPath: rnPath];
33+
}
34+
35+
+ (BOOL) clearFilesForPath: (NSString *) fullPath {
36+
37+
NSError *error = nil;
38+
NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:fullPath error: &error];
39+
if (error) {
40+
return NO;
41+
}
42+
43+
__block BOOL flag = YES;
44+
45+
[files enumerateObjectsUsingBlock:^(id _Nonnull fileName, NSUInteger idx, BOOL * _Nonnull stop) {
46+
47+
NSString *tmpfile = [fullPath stringByAppendingPathComponent: fileName];
48+
NSError *error = nil;
49+
if (![[NSFileManager defaultManager] removeItemAtPath:tmpfile error: &error]) {
50+
//error
51+
flag = NO;
52+
return ;
53+
}
54+
}];
55+
56+
return flag;
57+
}
58+
59+
60+
+(BOOL) createFolderAtPath: (NSString *) fullPath {
61+
62+
if ([[NSFileManager defaultManager] fileExistsAtPath: fullPath]) {
63+
return NO;
64+
}
65+
66+
NSError *error = nil;
67+
if (![[NSFileManager defaultManager] createDirectoryAtPath: fullPath withIntermediateDirectories:YES attributes:nil error: &error]) {
68+
return NO;
69+
}
70+
71+
return YES;
72+
}
73+
74+
+(BOOL) moveItems: (NSString *) srcPath toPath: (NSString *) destPath {
75+
76+
NSError *error = nil;
77+
NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:srcPath error: &error];
78+
if (error) {
79+
return NO;
80+
}
81+
82+
__block BOOL flag = YES;
83+
84+
[files enumerateObjectsUsingBlock:^(id _Nonnull fileName, NSUInteger idx, BOOL * _Nonnull stop) {
85+
86+
NSString *tmpSrcFile = [srcPath stringByAppendingPathComponent: fileName];
87+
NSString *tempDestFile = [destPath stringByAppendingPathComponent: fileName];
88+
89+
NSError *err = nil;
90+
if (![[NSFileManager defaultManager] moveItemAtPath:tmpSrcFile toPath:tempDestFile error: &err]) {
91+
92+
flag = NO;
93+
return ;
94+
}
95+
}];
96+
97+
return flag;
98+
}
99+
100+
+ (void) updateReactNativeLocalPath {
101+
102+
NSString *ldRNFullPath = [LDPatchFileManager getLDReactNativePath];
103+
if (![[NSFileManager defaultManager] fileExistsAtPath: ldRNFullPath]) {
104+
105+
[LDPatchFileManager createFolderAtPath: ldRNFullPath];
106+
107+
//do not backup
108+
NSURL *rnRootPath = [NSURL fileURLWithPath: ldRNFullPath];
109+
[rnRootPath setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil];
110+
111+
}
112+
113+
[[LDRNBundleList originBundles] enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull value, BOOL * _Nonnull stop) {
114+
115+
NSString *bundleName = key;
116+
117+
NSString *bizPath = [ldRNFullPath stringByAppendingPathComponent: bundleName];
118+
if (![[NSFileManager defaultManager] fileExistsAtPath: bizPath]) {
119+
120+
[LDPatchFileManager createFolderAtPath: bizPath];
121+
}
122+
123+
[[LDRNBundleList folders] enumerateObjectsUsingBlock:^(id _Nonnull folder, NSUInteger idx, BOOL * _Nonnull stop) {
124+
125+
NSString *tempPath = [bizPath stringByAppendingPathComponent: folder];
126+
if (![[NSFileManager defaultManager] fileExistsAtPath: tempPath]) {
127+
128+
[LDPatchFileManager createFolderAtPath: tempPath];
129+
}
130+
}];
131+
}];
132+
}
133+
134+
+ (void) copyLDBundleToReactNativePath {
135+
136+
NSString *ldRNFullPath = [LDPatchFileManager getLDReactNativePath];
137+
138+
[[LDRNBundleList originBundles] enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull value, BOOL * _Nonnull stop) {
139+
140+
NSString *bundleName = key;
141+
142+
NSString *srcPath = [[NSBundle mainBundle] pathForResource:bundleName ofType:@"zip"];
143+
NSString *originPath = [NSString stringWithFormat:@"%@/%@/%@", bundleName, [LDRNBundleList originFolder], [NSString stringWithFormat:@"%@.%@", bundleName, @"zip"]];
144+
NSString *destPath = [ldRNFullPath stringByAppendingPathComponent:originPath];
145+
146+
[LDPatchFileManager clearFilesForPath: [destPath stringByDeletingLastPathComponent]];
147+
148+
NSError *error = nil;
149+
if (![[NSFileManager defaultManager] copyItemAtPath:srcPath toPath:destPath error: &error]) {
150+
//error
151+
return ;
152+
}
153+
154+
[SSZipArchive unzipFileAtPath:destPath toDestination: [destPath stringByDeletingLastPathComponent]];
155+
[[NSFileManager defaultManager] removeItemAtPath:destPath error:nil];
156+
}];
157+
}
158+
159+
+(BOOL) validBundle:(NSString *) bundleName withFile: (NSString *) destPath withHashKey: (NSString *) hashKey {
160+
161+
NSString *md5 = [FileHash md5HashOfFileAtPath: destPath];
162+
NSArray *bundleList = [[NSUserDefaults standardUserDefaults] objectForKey: [LDRNBundleList rnSaveKey]];
163+
164+
__block NSDictionary *info = nil;
165+
[bundleList enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
166+
167+
if ([bundleName isEqualToString: obj[@"moduleName"]] && [obj[hashKey] isEqualToString: md5]) {
168+
169+
info = obj;
170+
return ;
171+
}
172+
}];
173+
174+
return info ? YES : NO;
175+
}
176+
177+
+(void) downloadPatchFile: (NSString *) url withBundle: (NSString *) bundleName {
178+
179+
NSString *savePath = [NSString stringWithFormat:@"%@/%@/%@", [LDPatchFileManager getLDReactNativePath], bundleName, [LDRNBundleList patchFolder]];
180+
[LDPatchFileManager download:url withSavePath: savePath withBundleName:bundleName];
181+
}
182+
183+
+ (void)download:(NSString *) fileUrl withSavePath: (NSString *) savePath withBundleName: (NSString *) bundleName {
184+
185+
NSURL *url = [NSURL URLWithString: fileUrl];
186+
187+
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
188+
NSURLSession *session = [NSURLSession sessionWithConfiguration: config];
189+
NSURLSessionDownloadTask *task = [session downloadTaskWithURL: url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
190+
191+
if (!error) {
192+
193+
NSArray *flags = [[NSUserDefaults standardUserDefaults] objectForKey:[LDRNBundleList rnDownloadKey]];
194+
NSMutableArray *downloadFlags = [NSMutableArray arrayWithArray:flags];
195+
[downloadFlags addObject: bundleName];
196+
[[NSUserDefaults standardUserDefaults] setObject:downloadFlags forKey: [LDRNBundleList rnDownloadKey]];
197+
198+
199+
NSString *destPath = [savePath stringByAppendingPathComponent: response.suggestedFilename];
200+
201+
[LDPatchFileManager clearFilesForPath: savePath];
202+
203+
[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath: destPath] error:nil];
204+
205+
//hash compare
206+
if (![LDPatchFileManager validBundle: bundleName withFile: destPath withHashKey:@"zipHash"]) {
207+
return ;
208+
}
209+
210+
[SSZipArchive unzipFileAtPath:destPath toDestination: [destPath stringByDeletingLastPathComponent]];
211+
[[NSFileManager defaultManager] removeItemAtPath: destPath error: nil];
212+
213+
[LDPatchFileManager mergePatchFile: [response.suggestedFilename stringByDeletingPathExtension]];
214+
}
215+
216+
}];
217+
218+
[task resume];
219+
}
220+
221+
+ (void) reloadAllJSPatch {
222+
223+
NSString *ldRNFullPath = [LDPatchFileManager getLDReactNativePath];
224+
if (![[NSFileManager defaultManager] fileExistsAtPath: ldRNFullPath]) {
225+
226+
[LDPatchFileManager copyLDBundleToReactNativePath];
227+
return;
228+
}
229+
230+
[[LDRNBundleList originBundles] enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull value, BOOL * _Nonnull stop) {
231+
232+
[LDPatchFileManager moveMergeFilesToIndex: key];
233+
}];
234+
}
235+
236+
+ (void) mergePatchFile: (NSString *) bundleName {
237+
238+
NSString *absoluteRoot = [[LDPatchFileManager getLDReactNativePath] stringByAppendingPathComponent: bundleName];
239+
240+
NSString *originfile = [NSString stringWithFormat:@"%@/%@/%@", absoluteRoot, [LDRNBundleList originFolder], [LDRNBundleList entryJSName]];
241+
NSString *patchfile = [NSString stringWithFormat:@"%@/%@/%@", absoluteRoot, [LDRNBundleList patchFolder], [LDRNBundleList patchFileName]];
242+
NSString *destfile = [NSString stringWithFormat:@"%@/%@/%@", absoluteRoot, [LDRNBundleList mergeFolder], [LDRNBundleList entryJSName]];
243+
244+
int ret = bspatch(originfile.UTF8String, destfile.UTF8String, patchfile.UTF8String);
245+
if (ret == -1) {
246+
//error
247+
[LDPatchFileManager clearFilesForPath: [destfile stringByDeletingLastPathComponent]];
248+
return;
249+
}
250+
251+
[[NSFileManager defaultManager] removeItemAtPath:patchfile error:nil];
252+
if (![LDPatchFileManager moveItems:[patchfile stringByDeletingLastPathComponent] toPath:[destfile stringByDeletingLastPathComponent]]) {
253+
//error
254+
[LDPatchFileManager clearFilesForPath: [patchfile stringByDeletingLastPathComponent]];
255+
return;
256+
}
257+
258+
if (![LDPatchFileManager validBundle: bundleName withFile:destfile withHashKey:@"jsbundleHash"]) {
259+
260+
[LDPatchFileManager clearFilesForPath: [patchfile stringByDeletingLastPathComponent]];
261+
return;
262+
}
263+
}
264+
265+
+ (void) moveMergeFilesToIndex: (NSString *) bundleName {
266+
267+
NSString *absoluteRoot = [[LDPatchFileManager getLDReactNativePath] stringByAppendingPathComponent: bundleName];
268+
269+
NSString *mergePath = [NSString stringWithFormat:@"%@/%@", absoluteRoot, [LDRNBundleList mergeFolder]];
270+
NSString *indexPath = [NSString stringWithFormat:@"%@/%@", absoluteRoot, [LDRNBundleList indexFolder]];
271+
272+
NSString *entryJSfile = [mergePath stringByAppendingPathComponent: [LDRNBundleList entryJSName]];
273+
if (![[NSFileManager defaultManager] fileExistsAtPath: entryJSfile]) {
274+
//not fount
275+
return ;
276+
}
277+
278+
[LDPatchFileManager clearFilesForPath: indexPath];
279+
[LDPatchFileManager moveItems:mergePath toPath:indexPath];
280+
}
281+
282+
+ (NSString *) jsbundleLocation: (NSString *) bundleName {
283+
284+
NSString *absoluteRoot = [[LDPatchFileManager getLDReactNativePath] stringByAppendingPathComponent: bundleName];
285+
286+
NSString *originfile = [NSString stringWithFormat:@"%@/%@/%@", absoluteRoot, [LDRNBundleList originFolder], [LDRNBundleList entryJSName]];
287+
NSString *indexfile = [NSString stringWithFormat:@"%@/%@/%@", absoluteRoot, [LDRNBundleList indexFolder], [LDRNBundleList entryJSName]];
288+
289+
if ([[NSFileManager defaultManager] fileExistsAtPath: indexfile] ||
290+
[LDPatchFileManager validBundle: bundleName withFile: indexfile withHashKey:@"jsbundleHash"]) {
291+
return indexfile;
292+
}
293+
294+
if ([[NSFileManager defaultManager] fileExistsAtPath: originfile]) {
295+
296+
if ([[LDRNBundleList originBundlesHash] count] < 1 ||
297+
[[[LDRNBundleList originBundlesHash] objectForKey:@"bundleName"] isEqualToString: [FileHash md5HashOfFileAtPath: originfile]]) {
298+
299+
return originfile;
300+
}
301+
}
302+
303+
[LDPatchFileManager copyLDBundleToReactNativePath];
304+
return originfile;
305+
}
306+
307+
308+
@end
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//
2+
// LDRNBundleList.h
3+
// demo
4+
//
5+
// Created by hong on 2017/8/20.
6+
// Copyright © 2017年 leadeon. All rights reserved.
7+
//
8+
9+
#import <Foundation/Foundation.h>
10+
11+
@interface LDRNBundleList : NSObject
12+
13+
+(NSString *) appKey;
14+
+(NSString *) versionUrl;
15+
+(NSString *) rnVersion;
16+
17+
+(NSString *) LDRNRootpath;
18+
+(NSDictionary *) originBundles;
19+
+(NSDictionary *) originBundlesHash;
20+
21+
+(NSString *) entryJSName;
22+
+(NSString *) patchFileName;
23+
24+
+(NSString *) resFolder;
25+
26+
+(NSArray *) folders;
27+
28+
+(NSString *) indexFolder;
29+
+(NSString *) mergeFolder;
30+
+(NSString *) patchFolder;
31+
+(NSString *) originFolder;
32+
33+
+(NSString *) rnSaveKey;
34+
+(NSString *) rnDownloadKey;
35+
+(NSString *) appInfoKey;
36+
37+
38+
@end

0 commit comments

Comments
 (0)