react-native-ota-hot-update 2.2.0 → 2.2.3

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
@@ -3,6 +3,11 @@
3
3
 
4
4
  This React Native module allows you to manage hot updates (in-app update) with minimal configuration, similar to Code Push. You can control versioning and host the JS bundle yourself. The library handles the installation of updates after the bundle is downloaded from your server or Git repository. With Code Push retiring soon, this library gives you full control over your update process, whether hosting the bundle on your own server or in a Git repository.
5
5
 
6
+ ### Key features:
7
+
8
+ - Host the bundle on your own server or in a Git repository.
9
+ - Rollback function
10
+ - Crash Handling: Handles crash exceptions when an incorrect bundle is updated and will automatically roll back to the previous bundle version.
6
11
 
7
12
  1. **Demo via server**
8
13
 
@@ -41,7 +41,6 @@ class CrashHandler(private val context: Context) : Thread.UncaughtExceptionHandl
41
41
  } else {
42
42
  sharedPrefs.putString(PATH, "")
43
43
  }
44
- sharedPrefs.putString(VERSION, "0")
45
44
  Toast.makeText(context, "Failed to load the update. Please try again.", Toast.LENGTH_LONG).show()
46
45
  GlobalScope.launch(Dispatchers.IO) {
47
46
  delay(1500)
@@ -1,7 +1,6 @@
1
1
  package com.otahotupdate
2
2
 
3
3
  import android.content.Context
4
- import android.content.pm.PackageInfo
5
4
  import android.content.pm.PackageManager
6
5
  import android.os.Build
7
6
  import com.facebook.react.BaseReactPackage
@@ -9,7 +8,7 @@ import com.facebook.react.bridge.NativeModule
9
8
  import com.facebook.react.bridge.ReactApplicationContext
10
9
  import com.facebook.react.module.model.ReactModuleInfo
11
10
  import com.facebook.react.module.model.ReactModuleInfoProvider
12
- import com.rnhotupdate.Common.CURRENT_VERSION_NAME
11
+ import com.rnhotupdate.Common.CURRENT_VERSION_CODE
13
12
  import com.rnhotupdate.Common.DEFAULT_BUNDLE
14
13
  import com.rnhotupdate.Common.PATH
15
14
  import com.rnhotupdate.Common.VERSION
@@ -41,12 +40,22 @@ class OtaHotUpdate : BaseReactPackage() {
41
40
  }
42
41
  }
43
42
  companion object {
44
- @Suppress("DEPRECATION")
45
- fun Context.getPackageInfo(): PackageInfo {
46
- return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
47
- packageManager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(0))
48
- } else {
49
- packageManager.getPackageInfo(packageName, 0)
43
+ fun Context.getVersionCode(): String {
44
+ return when {
45
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> {
46
+ packageManager.getPackageInfo(
47
+ packageName,
48
+ PackageManager.PackageInfoFlags.of(0)
49
+ ).longVersionCode.toString()
50
+ }
51
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.P -> {
52
+ @Suppress("DEPRECATION")
53
+ packageManager.getPackageInfo(packageName, 0).longVersionCode.toString()
54
+ }
55
+ else -> {
56
+ @Suppress("DEPRECATION")
57
+ packageManager.getPackageInfo(packageName, 0).versionCode.toString()
58
+ }
50
59
  }
51
60
  }
52
61
  fun bundleJS(context: Context): String {
@@ -54,8 +63,8 @@ class OtaHotUpdate : BaseReactPackage() {
54
63
  val sharedPrefs = SharedPrefs(context)
55
64
  val pathBundle = sharedPrefs.getString(PATH)
56
65
  val version = sharedPrefs.getString(VERSION)
57
- val currentVersionName = sharedPrefs.getString(CURRENT_VERSION_NAME)
58
- if (pathBundle == "" || (currentVersionName != context.getPackageInfo().versionName)) {
66
+ val currentVersionName = sharedPrefs.getString(CURRENT_VERSION_CODE)
67
+ if (pathBundle == "" || (currentVersionName != context.getVersionCode())) {
59
68
  if (version != "") {
60
69
  // reset version number because bundle is wrong version, need download from new version
61
70
  sharedPrefs.putString(VERSION, "")
@@ -5,11 +5,12 @@ import com.facebook.react.bridge.Promise
5
5
  import com.facebook.react.bridge.ReactApplicationContext
6
6
  import com.facebook.react.bridge.ReactMethod
7
7
  import com.jakewharton.processphoenix.ProcessPhoenix
8
- import com.otahotupdate.OtaHotUpdate.Companion.getPackageInfo
9
- import com.rnhotupdate.Common.CURRENT_VERSION_NAME
8
+ import com.otahotupdate.OtaHotUpdate.Companion.getVersionCode
9
+ import com.rnhotupdate.Common.CURRENT_VERSION_CODE
10
10
  import com.rnhotupdate.Common.PATH
11
11
  import com.rnhotupdate.Common.PREVIOUS_PATH
12
12
  import com.rnhotupdate.Common.VERSION
13
+ import com.rnhotupdate.Common.PREVIOUS_VERSION
13
14
  import com.rnhotupdate.Common.METADATA
14
15
  import com.rnhotupdate.SharedPrefs
15
16
  import java.io.File
@@ -38,8 +39,8 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
38
39
  }
39
40
  sharedPrefs.putString(PATH, fileUnzip)
40
41
  sharedPrefs.putString(
41
- CURRENT_VERSION_NAME,
42
- reactApplicationContext?.getPackageInfo()?.versionName
42
+ CURRENT_VERSION_CODE,
43
+ reactApplicationContext.getVersionCode()
43
44
  )
44
45
  promise.resolve(true)
45
46
  } else {
@@ -86,6 +87,12 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
86
87
  @ReactMethod
87
88
  override fun setCurrentVersion(version: String?, promise: Promise) {
88
89
  val sharedPrefs = SharedPrefs(reactApplicationContext)
90
+
91
+ val currentVersion = sharedPrefs.getString(VERSION)
92
+ if (currentVersion != "" && currentVersion != version) {
93
+ sharedPrefs.putString(PREVIOUS_VERSION, currentVersion)
94
+ }
95
+
89
96
  sharedPrefs.putString(VERSION, version)
90
97
  promise.resolve(true)
91
98
  }
@@ -114,8 +121,8 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
114
121
  val sharedPrefs = SharedPrefs(reactApplicationContext)
115
122
  sharedPrefs.putString(PATH, path)
116
123
  sharedPrefs.putString(
117
- CURRENT_VERSION_NAME,
118
- reactApplicationContext?.getPackageInfo()?.versionName
124
+ CURRENT_VERSION_CODE,
125
+ reactApplicationContext.getVersionCode()
119
126
  )
120
127
  promise.resolve(true)
121
128
  }
@@ -124,11 +131,21 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
124
131
  override fun rollbackToPreviousBundle(a: Double, promise: Promise) {
125
132
  val sharedPrefs = SharedPrefs(reactApplicationContext)
126
133
  val oldPath = sharedPrefs.getString(PREVIOUS_PATH)
134
+ val previousVersion = sharedPrefs.getString(PREVIOUS_VERSION)
135
+
127
136
  if (oldPath != "") {
128
137
  val isDeleted = utils.deleteOldBundleIfneeded(PATH)
129
138
  if (isDeleted) {
130
139
  sharedPrefs.putString(PATH, oldPath)
131
140
  sharedPrefs.putString(PREVIOUS_PATH, "")
141
+
142
+ if (previousVersion != "") {
143
+ sharedPrefs.putString(VERSION, previousVersion)
144
+ sharedPrefs.putString(PREVIOUS_VERSION, "")
145
+ } else {
146
+ sharedPrefs.putString(VERSION, "")
147
+ }
148
+
132
149
  promise.resolve(true)
133
150
  } else {
134
151
  promise.resolve(false)
@@ -27,7 +27,8 @@ object Common {
27
27
  val PATH = "PATH"
28
28
  val PREVIOUS_PATH = "PREVIOUS_PATH"
29
29
  val VERSION = "VERSION"
30
- val CURRENT_VERSION_NAME = "CURRENT_VERSION_NAME"
30
+ val PREVIOUS_VERSION = "PREVIOUS_VERSION"
31
+ val CURRENT_VERSION_CODE = "CURRENT_VERSION_CODE"
31
32
  val SHARED_PREFERENCE_NAME = "HOT-UPDATE-REACT_NATIVE"
32
33
  val DEFAULT_BUNDLE = "assets://index.android.bundle"
33
34
  val METADATA = "METADATA"
@@ -34,7 +34,6 @@ void OTAExceptionHandler(NSException *exception) {
34
34
  } else {
35
35
  [defaults removeObjectForKey:@"PATH"];
36
36
  }
37
- [defaults removeObjectForKey:@"VERSION"];
38
37
  [defaults synchronize];
39
38
  } else if (previousHandler) {
40
39
  previousHandler(exception);
@@ -134,6 +133,9 @@ void OTAExceptionHandler(NSException *exception) {
134
133
  NSURL *fileURL = [NSURL fileURLWithPath:retrievedString];
135
134
  return fileURL;
136
135
  } else {
136
+ // reset version number because bundle is wrong version, need download from new version
137
+ [defaults removeObjectForKey:@"VERSION"];
138
+ [defaults synchronize];
137
139
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
138
140
  }
139
141
  }
@@ -283,6 +285,14 @@ RCT_EXPORT_METHOD(rollbackToPreviousBundle:(double)i
283
285
  if (oldPath && [OtaHotUpdate isFilePathValid:oldPath]) {
284
286
  BOOL isDeleted = [OtaHotUpdate removeBundleIfNeeded:@"PATH"];
285
287
  if (isDeleted) {
288
+ NSString *previousVersion = [defaults stringForKey:@"PREVIOUS_VERSION"];
289
+ if (previousVersion) {
290
+ [defaults setObject:previousVersion forKey:@"VERSION"];
291
+ [defaults removeObjectForKey:@"PREVIOUS_VERSION"];
292
+ } else {
293
+ [defaults removeObjectForKey:@"VERSION"];
294
+ }
295
+
286
296
  [defaults setObject:oldPath forKey:@"PATH"];
287
297
  [defaults removeObjectForKey:@"OLD_PATH"];
288
298
  [defaults synchronize];
@@ -311,8 +321,14 @@ RCT_EXPORT_METHOD(getCurrentVersion:(double)a
311
321
  RCT_EXPORT_METHOD(setCurrentVersion:(NSString *)version
312
322
  resolve:(RCTPromiseResolveBlock)resolve
313
323
  reject:(RCTPromiseRejectBlock)reject) {
324
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
325
+ NSString *currentVersion = [defaults stringForKey:@"VERSION"];
326
+
314
327
  if (version) {
315
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
328
+ if (currentVersion && currentVersion != version) {
329
+ [defaults setObject:currentVersion forKey:@"PREVIOUS_VERSION"];
330
+ }
331
+
316
332
  [defaults setObject:version forKey:@"VERSION"];
317
333
  [defaults synchronize];
318
334
  resolve(@(YES));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-ota-hot-update",
3
- "version": "2.2.0",
3
+ "version": "2.2.3",
4
4
  "description": "Hot update for react native",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/commonjs/index.js",