@parrotnavy/rn-native-updates 0.9.1 → 0.10.0
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/android/src/main/java/com/parrotnavy/nativeupdates/NativeUpdatesModule.kt +143 -134
- package/android/src/main/java/com/parrotnavy/nativeupdates/NativeUpdatesPackage.kt +16 -0
- package/ios/NativeUpdatesBridge.m +10 -0
- package/ios/NativeUpdatesExceptions.swift +0 -2
- package/ios/NativeUpdatesModule.swift +91 -62
- package/lib/module/NativeUpdatesModule.js +8 -2
- package/lib/module/NativeUpdatesModule.js.map +1 -1
- package/lib/module/api.js +2 -5
- package/lib/module/api.js.map +1 -1
- package/lib/module/hooks/useAppUpdate.js +17 -23
- package/lib/module/hooks/useAppUpdate.js.map +1 -1
- package/lib/typescript/src/NativeUpdatesModule.d.ts.map +1 -1
- package/lib/typescript/src/api.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useAppUpdate.d.ts.map +1 -1
- package/package.json +1 -9
- package/rn-native-updates.podspec +2 -1
- package/src/NativeUpdatesModule.ts +13 -2
- package/src/api.ts +2 -3
- package/src/hooks/useAppUpdate.ts +23 -26
- package/android/src/main/java/com/parrotnavy/nativeupdates/NativeUpdatesExceptions.kt +0 -33
- package/expo-module.config.json +0 -9
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
package com.parrotnavy.nativeupdates
|
|
2
2
|
|
|
3
|
-
import android.app.Activity
|
|
4
3
|
import android.content.pm.PackageManager
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import com.
|
|
4
|
+
import com.facebook.react.bridge.Arguments
|
|
5
|
+
import com.facebook.react.bridge.Promise
|
|
6
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
7
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
8
|
+
import com.facebook.react.bridge.ReactMethod
|
|
9
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
10
10
|
import com.google.android.play.core.appupdate.AppUpdateManager
|
|
11
11
|
import com.google.android.play.core.appupdate.AppUpdateManagerFactory
|
|
12
12
|
import com.google.android.play.core.appupdate.AppUpdateOptions
|
|
@@ -16,156 +16,165 @@ import com.google.android.play.core.install.model.InstallStatus
|
|
|
16
16
|
import com.google.android.play.core.install.model.UpdateAvailability
|
|
17
17
|
import java.util.Locale
|
|
18
18
|
|
|
19
|
-
class NativeUpdatesModule :
|
|
19
|
+
class NativeUpdatesModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
|
20
20
|
private var appUpdateManager: AppUpdateManager? = null
|
|
21
21
|
private var installStateListener: InstallStateUpdatedListener? = null
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
get() = requireNotNull(appContext.reactContext)
|
|
23
|
+
override fun getName(): String = "NativeUpdates"
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
Constants {
|
|
33
|
-
val packageName = context.packageName
|
|
34
|
-
val packageInfo = try {
|
|
35
|
-
context.packageManager.getPackageInfo(packageName, 0)
|
|
36
|
-
} catch (e: PackageManager.NameNotFoundException) {
|
|
37
|
-
null
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
mapOf(
|
|
41
|
-
"currentVersion" to (packageInfo?.versionName ?: "0.0.0"),
|
|
42
|
-
"buildNumber" to (packageInfo?.longVersionCode?.toString() ?: "0"),
|
|
43
|
-
"packageName" to packageName,
|
|
44
|
-
"country" to Locale.getDefault().country
|
|
45
|
-
)
|
|
25
|
+
override fun getConstants(): MutableMap<String, Any> {
|
|
26
|
+
val packageName = reactApplicationContext.packageName
|
|
27
|
+
val packageInfo = try {
|
|
28
|
+
reactApplicationContext.packageManager.getPackageInfo(packageName, 0)
|
|
29
|
+
} catch (e: PackageManager.NameNotFoundException) {
|
|
30
|
+
null
|
|
46
31
|
}
|
|
47
32
|
|
|
48
|
-
|
|
33
|
+
return mutableMapOf(
|
|
34
|
+
"currentVersion" to (packageInfo?.versionName ?: "0.0.0"),
|
|
35
|
+
"buildNumber" to (packageInfo?.longVersionCode?.toString() ?: "0"),
|
|
36
|
+
"packageName" to packageName,
|
|
37
|
+
"country" to Locale.getDefault().country
|
|
38
|
+
)
|
|
39
|
+
}
|
|
49
40
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
41
|
+
override fun initialize() {
|
|
42
|
+
super.initialize()
|
|
43
|
+
appUpdateManager = AppUpdateManagerFactory.create(reactApplicationContext)
|
|
44
|
+
}
|
|
53
45
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
46
|
+
override fun onCatalystInstanceDestroy() {
|
|
47
|
+
installStateListener?.let {
|
|
48
|
+
appUpdateManager?.unregisterListener(it)
|
|
58
49
|
}
|
|
50
|
+
super.onCatalystInstanceDestroy()
|
|
51
|
+
}
|
|
59
52
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
53
|
+
@ReactMethod
|
|
54
|
+
fun checkPlayStoreUpdate(promise: Promise) {
|
|
55
|
+
val manager = appUpdateManager ?: run {
|
|
56
|
+
promise.reject("PLAY_STORE_NOT_AVAILABLE", "Play Store is not available on this device")
|
|
57
|
+
return
|
|
58
|
+
}
|
|
65
59
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
promise.resolve(result)
|
|
81
|
-
}
|
|
82
|
-
.addOnFailureListener { e ->
|
|
83
|
-
if (e.message?.contains("API not available") == true ||
|
|
84
|
-
e.message?.contains("not installed from Play Store") == true) {
|
|
85
|
-
promise.reject(NotFromPlayStoreException())
|
|
60
|
+
manager.appUpdateInfo
|
|
61
|
+
.addOnSuccessListener { info ->
|
|
62
|
+
val result = Arguments.createMap().apply {
|
|
63
|
+
putInt("updateAvailability", info.updateAvailability())
|
|
64
|
+
if (info.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
|
|
65
|
+
putInt("availableVersionCode", info.availableVersionCode())
|
|
66
|
+
} else {
|
|
67
|
+
putNull("availableVersionCode")
|
|
68
|
+
}
|
|
69
|
+
putBoolean("isFlexibleUpdateAllowed", info.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE))
|
|
70
|
+
putBoolean("isImmediateUpdateAllowed", info.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE))
|
|
71
|
+
val stalenessDays = info.clientVersionStalenessDays()
|
|
72
|
+
if (stalenessDays != null) {
|
|
73
|
+
putInt("clientVersionStalenessDays", stalenessDays)
|
|
86
74
|
} else {
|
|
87
|
-
|
|
75
|
+
putNull("clientVersionStalenessDays")
|
|
88
76
|
}
|
|
77
|
+
putInt("updatePriority", info.updatePriority())
|
|
78
|
+
putDouble("totalBytesToDownload", info.totalBytesToDownload().toDouble())
|
|
79
|
+
putString("packageName", info.packageName())
|
|
89
80
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
AsyncFunction("startUpdate") { updateType: Int, promise: Promise ->
|
|
93
|
-
val manager = appUpdateManager ?: run {
|
|
94
|
-
promise.reject(PlayStoreNotAvailableException())
|
|
95
|
-
return@AsyncFunction
|
|
81
|
+
promise.resolve(result)
|
|
96
82
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
83
|
+
.addOnFailureListener { e ->
|
|
84
|
+
if (e.message?.contains("API not available") == true ||
|
|
85
|
+
e.message?.contains("not installed from Play Store") == true) {
|
|
86
|
+
promise.reject("NOT_FROM_PLAY_STORE", "App was not installed from Play Store")
|
|
87
|
+
} else {
|
|
88
|
+
promise.reject("CHECK_FAILED", "Failed to check for updates${e.message?.let { ": $it" } ?: ""}")
|
|
89
|
+
}
|
|
101
90
|
}
|
|
91
|
+
}
|
|
102
92
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
93
|
+
@ReactMethod
|
|
94
|
+
fun startUpdate(updateType: Int, promise: Promise) {
|
|
95
|
+
val manager = appUpdateManager ?: run {
|
|
96
|
+
promise.reject("PLAY_STORE_NOT_AVAILABLE", "Play Store is not available on this device")
|
|
97
|
+
return
|
|
98
|
+
}
|
|
109
99
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
"
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
100
|
+
val activity = currentActivity ?: run {
|
|
101
|
+
promise.reject("NO_ACTIVITY", "No activity available to start update flow")
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
manager.appUpdateInfo
|
|
106
|
+
.addOnSuccessListener { info ->
|
|
107
|
+
if (info.updateAvailability() != UpdateAvailability.UPDATE_AVAILABLE) {
|
|
108
|
+
promise.reject("UPDATE_NOT_AVAILABLE", "No update is available")
|
|
109
|
+
return@addOnSuccessListener
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (updateType == AppUpdateType.FLEXIBLE) {
|
|
113
|
+
installStateListener = InstallStateUpdatedListener { state ->
|
|
114
|
+
val progress = if (state.totalBytesToDownload() > 0) {
|
|
115
|
+
((state.bytesDownloaded() * 100) / state.totalBytesToDownload()).toInt()
|
|
116
|
+
} else 0
|
|
117
|
+
|
|
118
|
+
when (state.installStatus()) {
|
|
119
|
+
InstallStatus.DOWNLOADING -> {
|
|
120
|
+
reactApplicationContext
|
|
121
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
122
|
+
.emit("onUpdateProgress", Arguments.createMap().apply {
|
|
123
|
+
putInt("installStatus", state.installStatus())
|
|
124
|
+
putDouble("bytesDownloaded", state.bytesDownloaded().toDouble())
|
|
125
|
+
putDouble("totalBytesToDownload", state.totalBytesToDownload().toDouble())
|
|
126
|
+
putInt("downloadProgress", progress)
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
InstallStatus.DOWNLOADED -> {
|
|
130
|
+
reactApplicationContext
|
|
131
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
132
|
+
.emit("onUpdateDownloaded", Arguments.createMap().apply {
|
|
133
|
+
putInt("installStatus", state.installStatus())
|
|
134
|
+
putDouble("bytesDownloaded", state.bytesDownloaded().toDouble())
|
|
135
|
+
putDouble("totalBytesToDownload", state.totalBytesToDownload().toDouble())
|
|
136
|
+
putInt("downloadProgress", 100)
|
|
137
|
+
})
|
|
147
138
|
}
|
|
139
|
+
InstallStatus.INSTALLED -> {
|
|
140
|
+
reactApplicationContext
|
|
141
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
142
|
+
.emit("onUpdateInstalled", Arguments.createMap().apply {
|
|
143
|
+
putInt("installStatus", state.installStatus())
|
|
144
|
+
})
|
|
145
|
+
installStateListener?.let { manager.unregisterListener(it) }
|
|
146
|
+
}
|
|
147
|
+
InstallStatus.FAILED, InstallStatus.CANCELED -> {
|
|
148
|
+
reactApplicationContext
|
|
149
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
150
|
+
.emit("onUpdateFailed", Arguments.createMap().apply {
|
|
151
|
+
putInt("installStatus", state.installStatus())
|
|
152
|
+
})
|
|
153
|
+
installStateListener?.let { manager.unregisterListener(it) }
|
|
154
|
+
}
|
|
155
|
+
else -> {}
|
|
148
156
|
}
|
|
149
|
-
manager.registerListener(installStateListener!!)
|
|
150
157
|
}
|
|
151
|
-
|
|
152
|
-
val options = AppUpdateOptions.newBuilder(updateType).build()
|
|
153
|
-
|
|
154
|
-
manager.startUpdateFlow(info, activity, options)
|
|
155
|
-
.addOnSuccessListener {
|
|
156
|
-
promise.resolve(null)
|
|
157
|
-
}
|
|
158
|
-
.addOnFailureListener { e ->
|
|
159
|
-
promise.reject(UpdateFailedException(e.message))
|
|
160
|
-
}
|
|
158
|
+
manager.registerListener(installStateListener!!)
|
|
161
159
|
}
|
|
162
|
-
.addOnFailureListener { e ->
|
|
163
|
-
promise.reject(CheckFailedException(e.message))
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
160
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
161
|
+
val options = AppUpdateOptions.newBuilder(updateType).build()
|
|
162
|
+
|
|
163
|
+
manager.startUpdateFlow(info, activity, options)
|
|
164
|
+
.addOnSuccessListener {
|
|
165
|
+
promise.resolve(null)
|
|
166
|
+
}
|
|
167
|
+
.addOnFailureListener { e ->
|
|
168
|
+
promise.reject("UPDATE_FAILED", "Failed to start update${e.message?.let { ": $it" } ?: ""}")
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
.addOnFailureListener { e ->
|
|
172
|
+
promise.reject("CHECK_FAILED", "Failed to check for updates${e.message?.let { ": $it" } ?: ""}")
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@ReactMethod
|
|
177
|
+
fun completeUpdate() {
|
|
178
|
+
appUpdateManager?.completeUpdate()
|
|
170
179
|
}
|
|
171
180
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package com.parrotnavy.nativeupdates
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
|
|
8
|
+
class NativeUpdatesPackage : ReactPackage {
|
|
9
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
10
|
+
return listOf(NativeUpdatesModule(reactContext))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
14
|
+
return emptyList()
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#import <React/RCTBridgeModule.h>
|
|
2
|
+
|
|
3
|
+
@interface RCT_EXTERN_MODULE(NativeUpdatesModule, NSObject)
|
|
4
|
+
|
|
5
|
+
RCT_EXTERN_METHOD(getAppStoreVersion:(NSString *)country
|
|
6
|
+
forceRefresh:(BOOL)forceRefresh
|
|
7
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
8
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
9
|
+
|
|
10
|
+
@end
|
|
@@ -1,77 +1,106 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
@objc(NativeUpdatesModule)
|
|
4
|
+
public class NativeUpdatesModule: NSObject, RCTBridgeModule {
|
|
4
5
|
private var cachedAppStoreInfo: [String: Any]?
|
|
5
6
|
private var cacheTimestamp: Date?
|
|
6
7
|
private let cacheDuration: TimeInterval = 3600 // 1 hour
|
|
7
8
|
|
|
8
|
-
public func
|
|
9
|
-
|
|
9
|
+
public static func moduleName() -> String! {
|
|
10
|
+
return "NativeUpdates"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public static func requiresMainQueueSetup() -> Bool {
|
|
14
|
+
return false
|
|
15
|
+
}
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
@objc func constantsToExport() -> [AnyHashable: Any]! {
|
|
18
|
+
return [
|
|
12
19
|
"currentVersion": Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "0.0.0",
|
|
13
20
|
"buildNumber": Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "0",
|
|
14
21
|
"packageName": Bundle.main.bundleIdentifier ?? "",
|
|
15
22
|
"country": Locale.current.region?.identifier ?? "US"
|
|
16
|
-
]
|
|
17
|
-
|
|
18
|
-
AsyncFunction("getAppStoreVersion") { (country: String?, forceRefresh: Bool) -> [String: Any] in
|
|
19
|
-
if !forceRefresh,
|
|
20
|
-
let cached = self.cachedAppStoreInfo,
|
|
21
|
-
let timestamp = self.cacheTimestamp,
|
|
22
|
-
Date().timeIntervalSince(timestamp) < self.cacheDuration {
|
|
23
|
-
return cached
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
guard let bundleId = Bundle.main.bundleIdentifier else {
|
|
27
|
-
throw AppStoreError.invalidBundleId
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
let countryCode = country ?? Locale.current.region?.identifier ?? "US"
|
|
31
|
-
let timestamp = Int(Date().timeIntervalSince1970)
|
|
32
|
-
let urlString = "https://itunes.apple.com/lookup?bundleId=\(bundleId)&country=\(countryCode)&date=\(timestamp)"
|
|
33
|
-
|
|
34
|
-
guard let url = URL(string: urlString) else {
|
|
35
|
-
throw AppStoreError.invalidURL
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
var request = URLRequest(url: url)
|
|
39
|
-
request.cachePolicy = .reloadIgnoringLocalCacheData
|
|
40
|
-
request.timeoutInterval = 30
|
|
41
|
-
|
|
42
|
-
let (data, response) = try await URLSession.shared.data(for: request)
|
|
43
|
-
|
|
44
|
-
guard let httpResponse = response as? HTTPURLResponse else {
|
|
45
|
-
throw AppStoreError.networkError
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if httpResponse.statusCode == 429 {
|
|
49
|
-
throw AppStoreError.rateLimited
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if httpResponse.statusCode != 200 {
|
|
53
|
-
throw AppStoreError.networkError
|
|
54
|
-
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
55
25
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
26
|
+
@objc func getAppStoreVersion(_ country: String?, forceRefresh: Bool, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
27
|
+
Task {
|
|
28
|
+
do {
|
|
29
|
+
if !forceRefresh,
|
|
30
|
+
let cached = self.cachedAppStoreInfo,
|
|
31
|
+
let timestamp = self.cacheTimestamp,
|
|
32
|
+
Date().timeIntervalSince(timestamp) < self.cacheDuration {
|
|
33
|
+
resolve(cached)
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
guard let bundleId = Bundle.main.bundleIdentifier else {
|
|
38
|
+
throw AppStoreError.invalidBundleId
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let countryCode = country ?? Locale.current.region?.identifier ?? "US"
|
|
42
|
+
let timestamp = Int(Date().timeIntervalSince1970)
|
|
43
|
+
let urlString = "https://itunes.apple.com/lookup?bundleId=\(bundleId)&country=\(countryCode)&date=\(timestamp)"
|
|
44
|
+
|
|
45
|
+
guard let url = URL(string: urlString) else {
|
|
46
|
+
throw AppStoreError.invalidURL
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
var request = URLRequest(url: url)
|
|
50
|
+
request.cachePolicy = .reloadIgnoringLocalCacheData
|
|
51
|
+
request.timeoutInterval = 30
|
|
52
|
+
|
|
53
|
+
let (data, response) = try await URLSession.shared.data(for: request)
|
|
54
|
+
|
|
55
|
+
guard let httpResponse = response as? HTTPURLResponse else {
|
|
56
|
+
throw AppStoreError.networkError
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if httpResponse.statusCode == 429 {
|
|
60
|
+
throw AppStoreError.rateLimited
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if httpResponse.statusCode != 200 {
|
|
64
|
+
throw AppStoreError.networkError
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
guard let json = try JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
68
|
+
let results = json["results"] as? [[String: Any]],
|
|
69
|
+
let first = results.first else {
|
|
70
|
+
throw AppStoreError.appNotFound
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let result: [String: Any] = [
|
|
74
|
+
"version": first["version"] as? String ?? "",
|
|
75
|
+
"trackId": first["trackId"] as? Int ?? 0,
|
|
76
|
+
"trackViewUrl": first["trackViewUrl"] as? String ?? "",
|
|
77
|
+
"currentVersionReleaseDate": first["currentVersionReleaseDate"] as? String ?? "",
|
|
78
|
+
"releaseNotes": first["releaseNotes"] as? String as Any,
|
|
79
|
+
"minimumOsVersion": first["minimumOsVersion"] as? String ?? ""
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
self.cachedAppStoreInfo = result
|
|
83
|
+
self.cacheTimestamp = Date()
|
|
84
|
+
|
|
85
|
+
resolve(result)
|
|
86
|
+
} catch let error as AppStoreError {
|
|
87
|
+
let code: String
|
|
88
|
+
switch error {
|
|
89
|
+
case .invalidBundleId:
|
|
90
|
+
code = "INVALID_BUNDLE_ID"
|
|
91
|
+
case .invalidURL:
|
|
92
|
+
code = "INVALID_URL"
|
|
93
|
+
case .networkError:
|
|
94
|
+
code = "NETWORK_ERROR"
|
|
95
|
+
case .appNotFound:
|
|
96
|
+
code = "APP_NOT_FOUND"
|
|
97
|
+
case .rateLimited:
|
|
98
|
+
code = "RATE_LIMITED"
|
|
99
|
+
}
|
|
100
|
+
reject(code, error.localizedDescription, error)
|
|
101
|
+
} catch {
|
|
102
|
+
reject("UNKNOWN", error.localizedDescription, error)
|
|
60
103
|
}
|
|
61
|
-
|
|
62
|
-
let result: [String: Any] = [
|
|
63
|
-
"version": first["version"] as? String ?? "",
|
|
64
|
-
"trackId": first["trackId"] as? Int ?? 0,
|
|
65
|
-
"trackViewUrl": first["trackViewUrl"] as? String ?? "",
|
|
66
|
-
"currentVersionReleaseDate": first["currentVersionReleaseDate"] as? String ?? "",
|
|
67
|
-
"releaseNotes": first["releaseNotes"] as? String as Any,
|
|
68
|
-
"minimumOsVersion": first["minimumOsVersion"] as? String ?? ""
|
|
69
|
-
]
|
|
70
|
-
|
|
71
|
-
self.cachedAppStoreInfo = result
|
|
72
|
-
self.cacheTimestamp = Date()
|
|
73
|
-
|
|
74
|
-
return result
|
|
75
104
|
}
|
|
76
105
|
}
|
|
77
106
|
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { NativeModules } from 'react-native';
|
|
4
|
+
const {
|
|
5
|
+
NativeUpdates
|
|
6
|
+
} = NativeModules;
|
|
7
|
+
if (!NativeUpdates) {
|
|
8
|
+
throw new Error('[@parrotnavy/rn-native-updates] NativeUpdates module is not available. ' + 'Make sure the library is properly linked. ' + 'For bare React Native: run `npx pod-install` (iOS) after installing. ' + 'For Expo: use a development build (`npx expo run:ios` or `npx expo run:android`).');
|
|
9
|
+
}
|
|
10
|
+
export const NativeUpdatesModule = NativeUpdates;
|
|
5
11
|
//# sourceMappingURL=NativeUpdatesModule.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["NativeModules","NativeUpdates","Error","NativeUpdatesModule"],"sourceRoot":"../../src","sources":["NativeUpdatesModule.ts"],"mappings":";;AAAA,SAASA,aAAa,QAAQ,cAAc;AAI5C,MAAM;EAAEC;AAAc,CAAC,GAAGD,aAAa;AAEvC,IAAI,CAACC,aAAa,EAAE;EAClB,MAAM,IAAIC,KAAK,CACb,yEAAyE,GACvE,4CAA4C,GAC5C,uEAAuE,GACvE,mFACJ,CAAC;AACH;AAEA,OAAO,MAAMC,mBAAmB,GAAGF,aAAwC","ignoreList":[]}
|
package/lib/module/api.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import { Linking, Platform } from 'react-native';
|
|
3
|
+
import { Linking, NativeEventEmitter, Platform } from 'react-native';
|
|
4
4
|
import { NativeUpdatesModule } from "./NativeUpdatesModule.js";
|
|
5
5
|
import { AppUpdateError, AppUpdateErrorCode, UpdateAvailability } from "./types.js";
|
|
6
6
|
import { isNewerVersion } from "./versionUtils.js";
|
|
@@ -116,10 +116,7 @@ let eventSubscription = null;
|
|
|
116
116
|
const listeners = new Set();
|
|
117
117
|
function setupEventListener() {
|
|
118
118
|
if (eventSubscription || Platform.OS !== 'android') return;
|
|
119
|
-
const
|
|
120
|
-
EventEmitter
|
|
121
|
-
} = require('expo-modules-core');
|
|
122
|
-
const emitter = new EventEmitter(NativeUpdatesModule);
|
|
119
|
+
const emitter = new NativeEventEmitter(NativeUpdatesModule);
|
|
123
120
|
const handleEvent = (_eventName, data) => {
|
|
124
121
|
const safeNumber = (val, def) => typeof val === 'number' && !Number.isNaN(val) ? val : def;
|
|
125
122
|
const state = {
|
package/lib/module/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Linking","Platform","NativeUpdatesModule","AppUpdateError","AppUpdateErrorCode","UpdateAvailability","isNewerVersion","getPackageName","packageName","getCurrentVersion","currentVersion","getCurrentBuildNumber","Number","parseInt","buildNumber","getCountry","country","getLatestVersion","options","OS","info","getAppStoreVersion","forceRefresh","version","checkPlayStoreUpdate","updateAvailability","UPDATE_AVAILABLE","availableVersionCode","toString","UNKNOWN","getStoreUrl","trackViewUrl","e","Error","message","String","needUpdate","depth","POSITIVE_INFINITY","latestVersion","storeUrl","isNeeded","openStore","url","canOpen","canOpenURL","openURL","getAppStoreInfo","startInAppUpdate","type","startUpdate","completeInAppUpdate","completeUpdate","eventSubscription","listeners","Set","setupEventListener","
|
|
1
|
+
{"version":3,"names":["Linking","NativeEventEmitter","Platform","NativeUpdatesModule","AppUpdateError","AppUpdateErrorCode","UpdateAvailability","isNewerVersion","getPackageName","packageName","getCurrentVersion","currentVersion","getCurrentBuildNumber","Number","parseInt","buildNumber","getCountry","country","getLatestVersion","options","OS","info","getAppStoreVersion","forceRefresh","version","checkPlayStoreUpdate","updateAvailability","UPDATE_AVAILABLE","availableVersionCode","toString","UNKNOWN","getStoreUrl","trackViewUrl","e","Error","message","String","needUpdate","depth","POSITIVE_INFINITY","latestVersion","storeUrl","isNeeded","openStore","url","canOpen","canOpenURL","openURL","getAppStoreInfo","startInAppUpdate","type","startUpdate","completeInAppUpdate","completeUpdate","eventSubscription","listeners","Set","setupEventListener","emitter","handleEvent","_eventName","data","safeNumber","val","def","isNaN","state","installStatus","bytesDownloaded","totalBytesToDownload","downloadProgress","listener","progressSub","addListener","downloadedSub","installedSub","failedSub","remove","addUpdateListener","add","delete","size"],"sourceRoot":"../../src","sources":["api.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
4
4
|
import { Platform } from 'react-native';
|
|
5
|
-
import { addUpdateListener, checkPlayStoreUpdate, completeInAppUpdate, getCurrentVersion, needUpdate, openStore, startInAppUpdate } from "../api.js";
|
|
5
|
+
import { addUpdateListener, checkPlayStoreUpdate, completeInAppUpdate, getCurrentBuildNumber, getCurrentVersion, getPackageName, needUpdate, openStore, startInAppUpdate } from "../api.js";
|
|
6
6
|
import { AppUpdateError, AppUpdateErrorCode, InstallStatus, UpdateAvailability } from "../types.js";
|
|
7
7
|
export function useAppUpdate(options) {
|
|
8
8
|
const [isChecking, setIsChecking] = useState(false);
|
|
@@ -22,29 +22,23 @@ export function useAppUpdate(options) {
|
|
|
22
22
|
setIsChecking(true);
|
|
23
23
|
setError(null);
|
|
24
24
|
try {
|
|
25
|
-
const result = await needUpdate({
|
|
26
|
-
country: options?.country,
|
|
27
|
-
forceRefresh: true
|
|
28
|
-
});
|
|
29
|
-
if (!mountedRef.current) return;
|
|
30
|
-
setIsUpdateAvailable(result.isNeeded);
|
|
31
|
-
setLatestVersion(result.latestVersion);
|
|
32
|
-
setStoreUrl(result.storeUrl);
|
|
33
25
|
if (Platform.OS === 'android') {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
26
|
+
const info = await checkPlayStoreUpdate();
|
|
27
|
+
if (!mountedRef.current) return;
|
|
28
|
+
setPlayStoreInfo(info);
|
|
29
|
+
const isAvailable = info.updateAvailability === UpdateAvailability.UPDATE_AVAILABLE;
|
|
30
|
+
setIsUpdateAvailable(isAvailable);
|
|
31
|
+
setLatestVersion(isAvailable && info.availableVersionCode ? info.availableVersionCode.toString() : getCurrentBuildNumber().toString());
|
|
32
|
+
setStoreUrl(`https://play.google.com/store/apps/details?id=${getPackageName()}`);
|
|
33
|
+
} else {
|
|
34
|
+
const result = await needUpdate({
|
|
35
|
+
country: options?.country,
|
|
36
|
+
forceRefresh: true
|
|
37
|
+
});
|
|
38
|
+
if (!mountedRef.current) return;
|
|
39
|
+
setIsUpdateAvailable(result.isNeeded);
|
|
40
|
+
setLatestVersion(result.latestVersion);
|
|
41
|
+
setStoreUrl(result.storeUrl);
|
|
48
42
|
}
|
|
49
43
|
} catch (e) {
|
|
50
44
|
if (!mountedRef.current) return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useEffect","useRef","useState","Platform","addUpdateListener","checkPlayStoreUpdate","completeInAppUpdate","getCurrentVersion","needUpdate","openStore","startInAppUpdate","AppUpdateError","AppUpdateErrorCode","InstallStatus","UpdateAvailability","useAppUpdate","options","isChecking","setIsChecking","isUpdateAvailable","setIsUpdateAvailable","currentVersion","latestVersion","setLatestVersion","storeUrl","setStoreUrl","error","setError","isDownloading","setIsDownloading","downloadProgress","setDownloadProgress","isReadyToInstall","setIsReadyToInstall","playStoreInfo","setPlayStoreInfo","subscriptionRef","mountedRef","checkUpdate","current","
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useRef","useState","Platform","addUpdateListener","checkPlayStoreUpdate","completeInAppUpdate","getCurrentBuildNumber","getCurrentVersion","getPackageName","needUpdate","openStore","startInAppUpdate","AppUpdateError","AppUpdateErrorCode","InstallStatus","UpdateAvailability","useAppUpdate","options","isChecking","setIsChecking","isUpdateAvailable","setIsUpdateAvailable","currentVersion","latestVersion","setLatestVersion","storeUrl","setStoreUrl","error","setError","isDownloading","setIsDownloading","downloadProgress","setDownloadProgress","isReadyToInstall","setIsReadyToInstall","playStoreInfo","setPlayStoreInfo","subscriptionRef","mountedRef","checkUpdate","current","OS","info","isAvailable","updateAvailability","UPDATE_AVAILABLE","availableVersionCode","toString","result","country","forceRefresh","isNeeded","e","appError","CHECK_FAILED","String","onError","handleOpenStore","UNKNOWN","handleStartUpdate","type","remove","state","installStatus","DOWNLOADING","DOWNLOADED","INSTALLED","FAILED","CANCELED","UPDATE_FAILED","handleCompleteUpdate","checkOnMount","startUpdate","completeUpdate"],"sourceRoot":"../../../src","sources":["hooks/useAppUpdate.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeUpdatesModule.d.ts","sourceRoot":"","sources":["../../../src/NativeUpdatesModule.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"NativeUpdatesModule.d.ts","sourceRoot":"","sources":["../../../src/NativeUpdatesModule.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAavD,eAAO,MAAM,mBAAmB,EAAoB,uBAAuB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/api.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,YAAY,EAGjB,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EAExB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,UAAU,EAChB,MAAM,SAAS,CAAC;AAGjB,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBzF;AAED,wBAAsB,WAAW,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwB/E;AAED,wBAAsB,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAwCvF;AAED,wBAAsB,SAAS,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAS3E;AAED,wBAAsB,eAAe,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,YAAY,CAAC,CAY9F;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,mBAAmB,CAAC,CASzE;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAStE;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAS1C;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/api.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,YAAY,EAGjB,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EAExB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,UAAU,EAChB,MAAM,SAAS,CAAC;AAGjB,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBzF;AAED,wBAAsB,WAAW,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwB/E;AAED,wBAAsB,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAwCvF;AAED,wBAAsB,SAAS,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAS3E;AAED,wBAAsB,eAAe,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,YAAY,CAAC,CAY9F;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,mBAAmB,CAAC,CASzE;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAStE;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAS1C;AAkDD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,cAAc,GAAG,kBAAkB,CAgB9E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAppUpdate.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useAppUpdate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useAppUpdate.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useAppUpdate.ts"],"names":[],"mappings":"AAcA,OAAO,EAQL,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACxB,MAAM,UAAU,CAAC;AAElB,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,kBAAkB,CAqK9E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parrotnavy/rn-native-updates",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "React Native app update checker with hooks support. Uses Play Core for Android and iTunes Lookup API for iOS.",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
"android",
|
|
19
19
|
"ios",
|
|
20
20
|
"*.podspec",
|
|
21
|
-
"expo-module.config.json",
|
|
22
21
|
"!ios/build",
|
|
23
22
|
"!android/build",
|
|
24
23
|
"!**/__tests__",
|
|
@@ -63,7 +62,6 @@
|
|
|
63
62
|
"@types/jest": "^29.5.0",
|
|
64
63
|
"@types/react": "^18.2.0",
|
|
65
64
|
"del-cli": "^6.0.0",
|
|
66
|
-
"expo-modules-core": "^2.0.0",
|
|
67
65
|
"jest": "^29.7.0",
|
|
68
66
|
"react": "^18.2.0",
|
|
69
67
|
"react-native": "^0.76.0",
|
|
@@ -73,15 +71,9 @@
|
|
|
73
71
|
"typescript": "^5.0.0"
|
|
74
72
|
},
|
|
75
73
|
"peerDependencies": {
|
|
76
|
-
"expo": "*",
|
|
77
74
|
"react": "*",
|
|
78
75
|
"react-native": ">=0.73.0"
|
|
79
76
|
},
|
|
80
|
-
"peerDependenciesMeta": {
|
|
81
|
-
"expo": {
|
|
82
|
-
"optional": true
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
77
|
"react-native-builder-bob": {
|
|
86
78
|
"source": "src",
|
|
87
79
|
"output": "lib",
|
|
@@ -14,6 +14,7 @@ Pod::Spec.new do |s|
|
|
|
14
14
|
s.source = { :git => package["repository"]["url"], :tag => "#{s.version}" }
|
|
15
15
|
|
|
16
16
|
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
|
17
|
+
s.public_header_files = "ios/**/*.h"
|
|
17
18
|
|
|
18
|
-
s.dependency "
|
|
19
|
+
s.dependency "React-Core"
|
|
19
20
|
end
|
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NativeModules } from 'react-native';
|
|
2
2
|
|
|
3
3
|
import type { NativeUpdatesModuleType } from './types';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
const { NativeUpdates } = NativeModules;
|
|
6
|
+
|
|
7
|
+
if (!NativeUpdates) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
'[@parrotnavy/rn-native-updates] NativeUpdates module is not available. ' +
|
|
10
|
+
'Make sure the library is properly linked. ' +
|
|
11
|
+
'For bare React Native: run `npx pod-install` (iOS) after installing. ' +
|
|
12
|
+
'For Expo: use a development build (`npx expo run:ios` or `npx expo run:android`).',
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const NativeUpdatesModule = NativeUpdates as NativeUpdatesModuleType;
|
package/src/api.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Linking, Platform } from 'react-native';
|
|
1
|
+
import { Linking, NativeEventEmitter, Platform } from 'react-native';
|
|
2
2
|
|
|
3
3
|
import { NativeUpdatesModule } from './NativeUpdatesModule';
|
|
4
4
|
import {
|
|
@@ -188,8 +188,7 @@ const listeners = new Set<UpdateListener>();
|
|
|
188
188
|
function setupEventListener(): void {
|
|
189
189
|
if (eventSubscription || Platform.OS !== 'android') return;
|
|
190
190
|
|
|
191
|
-
const
|
|
192
|
-
const emitter = new EventEmitter(NativeUpdatesModule);
|
|
191
|
+
const emitter = new NativeEventEmitter(NativeUpdatesModule as any);
|
|
193
192
|
|
|
194
193
|
const handleEvent = (_eventName: string, data: Record<string, unknown>) => {
|
|
195
194
|
const safeNumber = (val: unknown, def: number) =>
|
|
@@ -5,7 +5,9 @@ import {
|
|
|
5
5
|
addUpdateListener,
|
|
6
6
|
checkPlayStoreUpdate,
|
|
7
7
|
completeInAppUpdate,
|
|
8
|
+
getCurrentBuildNumber,
|
|
8
9
|
getCurrentVersion,
|
|
10
|
+
getPackageName,
|
|
9
11
|
needUpdate,
|
|
10
12
|
openStore,
|
|
11
13
|
startInAppUpdate,
|
|
@@ -45,35 +47,30 @@ export function useAppUpdate(options?: UseAppUpdateOptions): UseAppUpdateResult
|
|
|
45
47
|
setError(null);
|
|
46
48
|
|
|
47
49
|
try {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
});
|
|
50
|
+
if (Platform.OS === 'android') {
|
|
51
|
+
const info = await checkPlayStoreUpdate();
|
|
52
|
+
if (!mountedRef.current) return;
|
|
52
53
|
|
|
53
|
-
|
|
54
|
+
setPlayStoreInfo(info);
|
|
55
|
+
const isAvailable = info.updateAvailability === UpdateAvailability.UPDATE_AVAILABLE;
|
|
56
|
+
setIsUpdateAvailable(isAvailable);
|
|
57
|
+
setLatestVersion(
|
|
58
|
+
isAvailable && info.availableVersionCode
|
|
59
|
+
? info.availableVersionCode.toString()
|
|
60
|
+
: getCurrentBuildNumber().toString(),
|
|
61
|
+
);
|
|
62
|
+
setStoreUrl(`https://play.google.com/store/apps/details?id=${getPackageName()}`);
|
|
63
|
+
} else {
|
|
64
|
+
const result = await needUpdate({
|
|
65
|
+
country: options?.country,
|
|
66
|
+
forceRefresh: true,
|
|
67
|
+
});
|
|
54
68
|
|
|
55
|
-
|
|
56
|
-
setLatestVersion(result.latestVersion);
|
|
57
|
-
setStoreUrl(result.storeUrl);
|
|
69
|
+
if (!mountedRef.current) return;
|
|
58
70
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (mountedRef.current) {
|
|
63
|
-
setPlayStoreInfo(info);
|
|
64
|
-
setIsUpdateAvailable(info.updateAvailability === UpdateAvailability.UPDATE_AVAILABLE);
|
|
65
|
-
}
|
|
66
|
-
} catch (e) {
|
|
67
|
-
if (mountedRef.current) {
|
|
68
|
-
setPlayStoreInfo(null);
|
|
69
|
-
const appError =
|
|
70
|
-
e instanceof AppUpdateError
|
|
71
|
-
? e
|
|
72
|
-
: new AppUpdateError(AppUpdateErrorCode.CHECK_FAILED, String(e));
|
|
73
|
-
setError(appError);
|
|
74
|
-
options?.onError?.(appError);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
71
|
+
setIsUpdateAvailable(result.isNeeded);
|
|
72
|
+
setLatestVersion(result.latestVersion);
|
|
73
|
+
setStoreUrl(result.storeUrl);
|
|
77
74
|
}
|
|
78
75
|
} catch (e) {
|
|
79
76
|
if (!mountedRef.current) return;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
package com.parrotnavy.nativeupdates
|
|
2
|
-
|
|
3
|
-
import expo.modules.kotlin.exception.CodedException
|
|
4
|
-
|
|
5
|
-
class PlayStoreNotAvailableException : CodedException(
|
|
6
|
-
code = "PLAY_STORE_NOT_AVAILABLE",
|
|
7
|
-
message = "Play Store is not available on this device"
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
class NotFromPlayStoreException : CodedException(
|
|
11
|
-
code = "NOT_FROM_PLAY_STORE",
|
|
12
|
-
message = "App was not installed from Play Store"
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
class CheckFailedException(detail: String? = null) : CodedException(
|
|
16
|
-
code = "CHECK_FAILED",
|
|
17
|
-
message = "Failed to check for updates${detail?.let { ": $it" } ?: ""}"
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
class UpdateNotAvailableException : CodedException(
|
|
21
|
-
code = "UPDATE_NOT_AVAILABLE",
|
|
22
|
-
message = "No update is available"
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
class UpdateFailedException(detail: String? = null) : CodedException(
|
|
26
|
-
code = "UPDATE_FAILED",
|
|
27
|
-
message = "Failed to start update${detail?.let { ": $it" } ?: ""}"
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
class NoActivityException : CodedException(
|
|
31
|
-
code = "NO_ACTIVITY",
|
|
32
|
-
message = "No activity available to start update flow"
|
|
33
|
-
)
|