react-native-ota-hot-update 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -55,8 +55,8 @@ Here is the guideline to control bundle js by yourself, in here i am using Fireb
|
|
|
55
55
|
#### 1.Add these script into your package.json to export bundlejs file:
|
|
56
56
|
```bash
|
|
57
57
|
"scripts": {
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
"export-android": "mkdir -p android/output && react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/output/index.android.bundle --assets-dest android/output && cd android && find output -type f | zip index.android.bundle.zip -@ && cd .. && rm -rf android/output",
|
|
59
|
+
"export-ios": "mkdir -p ios/output && react-native bundle --platform ios --dev false --entry-file index.js --bundle-output ios/output/main.jsbundle --assets-dest ios/output && cd ios && find output -type f | zip main.jsbundle.zip -@ && cd .. && rm -rf ios/output"
|
|
60
60
|
}
|
|
61
61
|
```
|
|
62
62
|
These commands are export bundle file and compress it as a zip file, one for android and one for ios. You can create your own script that export and auto upload to your server.
|
|
@@ -4,7 +4,6 @@ import android.content.Context;
|
|
|
4
4
|
import android.content.Intent;
|
|
5
5
|
import android.util.Log;
|
|
6
6
|
|
|
7
|
-
import com.facebook.react.ReactInstanceManager;
|
|
8
7
|
import com.facebook.react.bridge.Promise;
|
|
9
8
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
10
9
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
@@ -23,12 +22,28 @@ public class HotUpdateModule extends ReactContextBaseJavaModule {
|
|
|
23
22
|
super(reactContext);
|
|
24
23
|
}
|
|
25
24
|
|
|
25
|
+
private boolean deleteDirectory(File directory) {
|
|
26
|
+
if (directory.isDirectory()) {
|
|
27
|
+
// List all files and directories in the current directory
|
|
28
|
+
File[] files = directory.listFiles();
|
|
29
|
+
if (files != null) {
|
|
30
|
+
// Recursively delete all files and directories
|
|
31
|
+
for (File file : files) {
|
|
32
|
+
if (!deleteDirectory(file)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Finally, delete the empty directory or file
|
|
39
|
+
return directory.delete();
|
|
40
|
+
}
|
|
26
41
|
private boolean deleteOldBundleIfneeded() {
|
|
27
42
|
SharedPrefs sharedPrefs = new SharedPrefs(getReactApplicationContext());
|
|
28
43
|
String path = sharedPrefs.getString(Common.INSTANCE.getPATH());
|
|
29
44
|
File file = new File(path);
|
|
30
45
|
if (file.exists() && file.isFile()) {
|
|
31
|
-
boolean isDeleted = file.
|
|
46
|
+
boolean isDeleted = deleteDirectory(file.getParentFile());
|
|
32
47
|
sharedPrefs.clear();
|
|
33
48
|
return isDeleted;
|
|
34
49
|
} else {
|
|
@@ -38,7 +53,7 @@ public class HotUpdateModule extends ReactContextBaseJavaModule {
|
|
|
38
53
|
private String unzip(File zipFile) {
|
|
39
54
|
File destDir = zipFile.getParentFile(); // Directory of the zip file
|
|
40
55
|
|
|
41
|
-
String
|
|
56
|
+
String bundleFilePath = null;
|
|
42
57
|
if (!destDir.exists()) {
|
|
43
58
|
destDir.mkdirs();
|
|
44
59
|
}
|
|
@@ -63,13 +78,15 @@ public class HotUpdateModule extends ReactContextBaseJavaModule {
|
|
|
63
78
|
}
|
|
64
79
|
}
|
|
65
80
|
}
|
|
66
|
-
|
|
67
|
-
|
|
81
|
+
if (newFile.getAbsolutePath().contains(".bundle")) {
|
|
82
|
+
bundleFilePath = newFile.getAbsolutePath();
|
|
83
|
+
}
|
|
68
84
|
}
|
|
85
|
+
zis.closeEntry();
|
|
69
86
|
} catch (Exception e) {
|
|
70
87
|
return null;
|
|
71
88
|
}
|
|
72
|
-
return
|
|
89
|
+
return bundleFilePath;
|
|
73
90
|
}
|
|
74
91
|
|
|
75
92
|
@ReactMethod
|
|
@@ -99,6 +116,8 @@ public class HotUpdateModule extends ReactContextBaseJavaModule {
|
|
|
99
116
|
@ReactMethod
|
|
100
117
|
public void deleteBundle(Promise promise) {
|
|
101
118
|
boolean isDeleted = deleteOldBundleIfneeded();
|
|
119
|
+
SharedPrefs sharedPrefs = new SharedPrefs(getReactApplicationContext());
|
|
120
|
+
sharedPrefs.putString(Common.INSTANCE.getVERSION(), "0");
|
|
102
121
|
promise.resolve(isDeleted);
|
|
103
122
|
}
|
|
104
123
|
@ReactMethod
|
package/ios/RNhotupdate.m
CHANGED
|
@@ -14,8 +14,9 @@ RCT_EXPORT_MODULE()
|
|
|
14
14
|
- (BOOL)removeBundleIfNeeded {
|
|
15
15
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
16
16
|
NSString *retrievedString = [defaults stringForKey:@"PATH"];
|
|
17
|
+
NSError *error = nil;
|
|
17
18
|
if (retrievedString && [self isFilePathValid:retrievedString]) {
|
|
18
|
-
BOOL isDeleted = [self
|
|
19
|
+
BOOL isDeleted = [self deleteAllContentsOfParentDirectoryOfFile:retrievedString error:&error];
|
|
19
20
|
[defaults removeObjectForKey:@"PATH"];
|
|
20
21
|
[defaults synchronize];
|
|
21
22
|
return isDeleted;
|
|
@@ -34,6 +35,53 @@ RCT_EXPORT_MODULE()
|
|
|
34
35
|
}
|
|
35
36
|
return success;
|
|
36
37
|
}
|
|
38
|
+
|
|
39
|
+
- (BOOL)deleteAllContentsOfParentDirectoryOfFile:(NSString *)filePath error:(NSError **)error {
|
|
40
|
+
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
41
|
+
|
|
42
|
+
// Get the parent directory of the file
|
|
43
|
+
NSString *parentDirectory = [filePath stringByDeletingLastPathComponent];
|
|
44
|
+
|
|
45
|
+
// Ensure the parent directory exists
|
|
46
|
+
BOOL isDirectory;
|
|
47
|
+
if (![fileManager fileExistsAtPath:parentDirectory isDirectory:&isDirectory] || !isDirectory) {
|
|
48
|
+
if (error) {
|
|
49
|
+
*error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileReadNoSuchFileError userInfo:@{NSLocalizedDescriptionKey: @"Parent directory does not exist or is not a directory."}];
|
|
50
|
+
}
|
|
51
|
+
return NO;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Get the contents of the parent directory
|
|
55
|
+
NSArray *contents = [fileManager contentsOfDirectoryAtPath:parentDirectory error:error];
|
|
56
|
+
if (error && *error) {
|
|
57
|
+
return NO;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
BOOL success = YES;
|
|
61
|
+
for (NSString *fileName in contents) {
|
|
62
|
+
NSString *filePathInDirectory = [parentDirectory stringByAppendingPathComponent:fileName];
|
|
63
|
+
|
|
64
|
+
BOOL isDirectory;
|
|
65
|
+
if ([fileManager fileExistsAtPath:filePathInDirectory isDirectory:&isDirectory]) {
|
|
66
|
+
NSError *removeError = nil;
|
|
67
|
+
if (isDirectory) {
|
|
68
|
+
// Recursively delete directory contents
|
|
69
|
+
if (![fileManager removeItemAtPath:filePathInDirectory error:&removeError]) {
|
|
70
|
+
NSLog(@"Failed to delete directory at path: %@", filePathInDirectory);
|
|
71
|
+
success = NO;
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
// Delete file
|
|
75
|
+
if (![fileManager removeItemAtPath:filePathInDirectory error:&removeError]) {
|
|
76
|
+
NSLog(@"Failed to delete file at path: %@", filePathInDirectory);
|
|
77
|
+
success = NO;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return success;
|
|
84
|
+
}
|
|
37
85
|
+ (BOOL)isFilePathExist:(NSString *)path {
|
|
38
86
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
39
87
|
return [fileManager fileExistsAtPath:path];
|
|
@@ -49,7 +97,36 @@ RCT_EXPORT_MODULE()
|
|
|
49
97
|
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
|
50
98
|
}
|
|
51
99
|
}
|
|
100
|
+
- (NSString *)searchForJsBundleInDirectory:(NSString *)directoryPath {
|
|
101
|
+
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
102
|
+
NSError *error;
|
|
103
|
+
|
|
104
|
+
// Get contents of the directory
|
|
105
|
+
NSArray *contents = [fileManager contentsOfDirectoryAtPath:directoryPath error:&error];
|
|
106
|
+
if (error) {
|
|
107
|
+
NSLog(@"Error reading directory contents: %@", error.localizedDescription);
|
|
108
|
+
return nil;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
for (NSString *file in contents) {
|
|
112
|
+
NSString *filePath = [directoryPath stringByAppendingPathComponent:file];
|
|
113
|
+
BOOL isDirectory;
|
|
114
|
+
if ([fileManager fileExistsAtPath:filePath isDirectory:&isDirectory]) {
|
|
115
|
+
if (isDirectory) {
|
|
116
|
+
// Recursively search in subdirectories
|
|
117
|
+
NSString *foundPath = [self searchForJsBundleInDirectory:filePath];
|
|
118
|
+
if (foundPath) {
|
|
119
|
+
return foundPath;
|
|
120
|
+
}
|
|
121
|
+
} else if ([filePath hasSuffix:@".jsbundle"]) {
|
|
122
|
+
// Return the path if it's a .jsbundle file
|
|
123
|
+
return filePath;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
52
127
|
|
|
128
|
+
return nil;
|
|
129
|
+
}
|
|
53
130
|
- (NSString *)unzipFileAtPath:(NSString *)zipFilePath {
|
|
54
131
|
// Define the directory where the files will be extracted
|
|
55
132
|
NSString *extractedFolderPath = [[zipFilePath stringByDeletingPathExtension] stringByAppendingPathExtension:@"unzip"];
|
|
@@ -73,11 +150,8 @@ RCT_EXPORT_MODULE()
|
|
|
73
150
|
NSLog(@"Failed to unzip file");
|
|
74
151
|
return nil;
|
|
75
152
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
NSArray *contents = [fileManager contentsOfDirectoryAtPath:extractedFolderPath error:nil];
|
|
79
|
-
if (contents.count == 1) {
|
|
80
|
-
NSString *filePath = [extractedFolderPath stringByAppendingPathComponent:contents.firstObject];
|
|
153
|
+
// Find .jsbundle files in the extracted directory
|
|
154
|
+
NSString *jsbundleFilePath = [self searchForJsBundleInDirectory:extractedFolderPath];
|
|
81
155
|
|
|
82
156
|
// Delete the zip file after extraction
|
|
83
157
|
NSError *removeError = nil;
|
|
@@ -85,14 +159,9 @@ RCT_EXPORT_MODULE()
|
|
|
85
159
|
if (removeError) {
|
|
86
160
|
NSLog(@"Failed to delete zip file: %@", removeError.localizedDescription);
|
|
87
161
|
}
|
|
88
|
-
|
|
89
|
-
// Return the
|
|
90
|
-
return
|
|
91
|
-
} else {
|
|
92
|
-
[self deleteFileAtPath:zipFilePath];
|
|
93
|
-
NSLog(@"Expected one file in the zip but found %lu", (unsigned long)contents.count);
|
|
94
|
-
return nil;
|
|
95
|
-
}
|
|
162
|
+
NSLog(@"File path----: %@", jsbundleFilePath);
|
|
163
|
+
// Return the .jsbundle file path or nil if not found
|
|
164
|
+
return jsbundleFilePath;
|
|
96
165
|
}
|
|
97
166
|
|
|
98
167
|
// Expose setupBundlePath method to JavaScript
|