@onekeyfe/react-native-device-utils 3.0.63 → 3.0.64
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/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt +7 -0
- package/ios/ReactNativeDeviceUtils.swift +40 -0
- package/lib/typescript/src/ReactNativeDeviceUtils.nitro.d.ts +1 -0
- package/nitrogen/generated/android/c++/JHybridReactNativeDeviceUtilsSpec.cpp +16 -0
- package/nitrogen/generated/android/c++/JHybridReactNativeDeviceUtilsSpec.hpp +1 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativedeviceutils/HybridReactNativeDeviceUtilsSpec.kt +4 -0
- package/nitrogen/generated/ios/c++/HybridReactNativeDeviceUtilsSpecSwift.hpp +8 -0
- package/nitrogen/generated/ios/swift/HybridReactNativeDeviceUtilsSpec.swift +1 -0
- package/nitrogen/generated/ios/swift/HybridReactNativeDeviceUtilsSpec_cxx.swift +19 -0
- package/nitrogen/generated/shared/c++/HybridReactNativeDeviceUtilsSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridReactNativeDeviceUtilsSpec.hpp +1 -0
- package/package.json +1 -1
- package/src/ReactNativeDeviceUtils.nitro.ts +4 -0
package/android/src/main/java/com/margelo/nitro/reactnativedeviceutils/ReactNativeDeviceUtils.kt
CHANGED
|
@@ -907,6 +907,13 @@ class ReactNativeDeviceUtils : HybridReactNativeDeviceUtilsSpec(), LifecycleEven
|
|
|
907
907
|
}
|
|
908
908
|
}
|
|
909
909
|
|
|
910
|
+
// iOS-only: cold-start LOCAL notification deep-link payload. Android delivers
|
|
911
|
+
// notification taps through the launching Intent's extras, a separate path,
|
|
912
|
+
// so there is nothing to hand back here.
|
|
913
|
+
override fun getAndClearColdStartLocalNotification(): Promise<String> {
|
|
914
|
+
return Promise.resolved("")
|
|
915
|
+
}
|
|
916
|
+
|
|
910
917
|
// MARK: - ExitModule
|
|
911
918
|
|
|
912
919
|
override fun exitApp() {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import NitroModules
|
|
2
2
|
import UIKit
|
|
3
3
|
import ReactNativeNativeLogger
|
|
4
|
+
import os
|
|
4
5
|
|
|
5
6
|
@objcMembers
|
|
6
7
|
public class LaunchOptionsStore: NSObject {
|
|
@@ -21,8 +22,38 @@ public class LaunchOptionsStore: NSObject {
|
|
|
21
22
|
public var deviceToken: Data?
|
|
22
23
|
public var startupTime: TimeInterval = 0
|
|
23
24
|
|
|
25
|
+
// Cold-start deep-link: the JSON `userInfo` of a LOCAL notification the user
|
|
26
|
+
// tapped to launch the (killed) app. The legacy `NotificationCenter` broadcast
|
|
27
|
+
// in AppDelegate is fire-and-forget and is lost on cold start because JS has
|
|
28
|
+
// not registered a listener yet; this slot is a pull buffer JS drains once it
|
|
29
|
+
// boots. In-memory ONLY (no NSUserDefaults): a new process = fresh `nil`, so
|
|
30
|
+
// it is naturally launch-scoped and cannot replay a stale tap on a later
|
|
31
|
+
// unrelated cold start. AppDelegate writes it via KVC
|
|
32
|
+
// (`setValue(_:forKey:"coldStartLocalNotification")`), same bridge as the
|
|
33
|
+
// properties above.
|
|
34
|
+
public var coldStartLocalNotification: String?
|
|
35
|
+
|
|
24
36
|
private static let deviceTokenKey = "1k_device_token"
|
|
25
37
|
|
|
38
|
+
// Serializes access to `coldStartLocalNotification`. The getter resolves on a
|
|
39
|
+
// nitro background thread (Promise.async) while AppDelegate writes the slot on
|
|
40
|
+
// the main thread during launch, so the read-and-clear below must be one
|
|
41
|
+
// critical section to avoid a double-drain race (delivering the deep-link
|
|
42
|
+
// twice) and memory-visibility issues. NOTE: AppDelegate writes via KVC
|
|
43
|
+
// (`setValue(_:forKey:)`), which bypasses this lock, so we cannot fully
|
|
44
|
+
// synchronize the writer from here — we protect the take side as best we can.
|
|
45
|
+
private var coldStartLock = os_unfair_lock()
|
|
46
|
+
|
|
47
|
+
// Read-once: hand the payload to JS exactly once per launch. The read+clear is
|
|
48
|
+
// performed atomically under `coldStartLock`.
|
|
49
|
+
public func takeColdStartLocalNotification() -> String {
|
|
50
|
+
os_unfair_lock_lock(&coldStartLock)
|
|
51
|
+
defer { os_unfair_lock_unlock(&coldStartLock) }
|
|
52
|
+
let value = coldStartLocalNotification ?? ""
|
|
53
|
+
coldStartLocalNotification = nil
|
|
54
|
+
return value
|
|
55
|
+
}
|
|
56
|
+
|
|
26
57
|
public func getDeviceTokenString() -> String {
|
|
27
58
|
// Prefer the JS-saved token (persisted across launches)
|
|
28
59
|
if let saved = UserDefaults.standard.string(forKey: LaunchOptionsStore.deviceTokenKey), !saved.isEmpty {
|
|
@@ -189,6 +220,15 @@ class ReactNativeDeviceUtils: HybridReactNativeDeviceUtilsSpec {
|
|
|
189
220
|
}
|
|
190
221
|
}
|
|
191
222
|
|
|
223
|
+
func getAndClearColdStartLocalNotification() throws -> Promise<String> {
|
|
224
|
+
return Promise.async {
|
|
225
|
+
let value = LaunchOptionsStore.shared.takeColdStartLocalNotification()
|
|
226
|
+
// Presence only — never log the payload (it's a deep-link target / PII).
|
|
227
|
+
OneKeyLog.info("DeviceUtils", "getAndClearColdStartLocalNotification: hasPayload=\(!value.isEmpty)")
|
|
228
|
+
return value
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
192
232
|
// MARK: - ExitModule
|
|
193
233
|
|
|
194
234
|
func exitApp() throws {
|
|
@@ -40,6 +40,7 @@ export interface ReactNativeDeviceUtils extends HybridObject<{
|
|
|
40
40
|
saveDeviceToken(token: string): Promise<void>;
|
|
41
41
|
registerDeviceToken(): Promise<boolean>;
|
|
42
42
|
getStartupTime(): Promise<number>;
|
|
43
|
+
getAndClearColdStartLocalNotification(): Promise<string>;
|
|
43
44
|
exitApp(): void;
|
|
44
45
|
getCurrentWebViewPackageInfo(): Promise<WebViewPackageInfo>;
|
|
45
46
|
isGooglePlayServicesAvailable(): Promise<GooglePlayServicesStatus>;
|
|
@@ -244,6 +244,22 @@ namespace margelo::nitro::reactnativedeviceutils {
|
|
|
244
244
|
return __promise;
|
|
245
245
|
}();
|
|
246
246
|
}
|
|
247
|
+
std::shared_ptr<Promise<std::string>> JHybridReactNativeDeviceUtilsSpec::getAndClearColdStartLocalNotification() {
|
|
248
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("getAndClearColdStartLocalNotification");
|
|
249
|
+
auto __result = method(_javaPart);
|
|
250
|
+
return [&]() {
|
|
251
|
+
auto __promise = Promise<std::string>::create();
|
|
252
|
+
__result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
|
|
253
|
+
auto __result = jni::static_ref_cast<jni::JString>(__boxedResult);
|
|
254
|
+
__promise->resolve(__result->toStdString());
|
|
255
|
+
});
|
|
256
|
+
__result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
|
|
257
|
+
jni::JniException __jniError(__throwable);
|
|
258
|
+
__promise->reject(std::make_exception_ptr(__jniError));
|
|
259
|
+
});
|
|
260
|
+
return __promise;
|
|
261
|
+
}();
|
|
262
|
+
}
|
|
247
263
|
void JHybridReactNativeDeviceUtilsSpec::exitApp() {
|
|
248
264
|
static const auto method = javaClassStatic()->getMethod<void()>("exitApp");
|
|
249
265
|
method(_javaPart);
|
|
@@ -69,6 +69,7 @@ namespace margelo::nitro::reactnativedeviceutils {
|
|
|
69
69
|
std::shared_ptr<Promise<void>> saveDeviceToken(const std::string& token) override;
|
|
70
70
|
std::shared_ptr<Promise<bool>> registerDeviceToken() override;
|
|
71
71
|
std::shared_ptr<Promise<double>> getStartupTime() override;
|
|
72
|
+
std::shared_ptr<Promise<std::string>> getAndClearColdStartLocalNotification() override;
|
|
72
73
|
void exitApp() override;
|
|
73
74
|
std::shared_ptr<Promise<WebViewPackageInfo>> getCurrentWebViewPackageInfo() override;
|
|
74
75
|
std::shared_ptr<Promise<GooglePlayServicesStatus>> isGooglePlayServicesAvailable() override;
|
|
@@ -111,6 +111,10 @@ abstract class HybridReactNativeDeviceUtilsSpec: HybridObject() {
|
|
|
111
111
|
@Keep
|
|
112
112
|
abstract fun getStartupTime(): Promise<Double>
|
|
113
113
|
|
|
114
|
+
@DoNotStrip
|
|
115
|
+
@Keep
|
|
116
|
+
abstract fun getAndClearColdStartLocalNotification(): Promise<String>
|
|
117
|
+
|
|
114
118
|
@DoNotStrip
|
|
115
119
|
@Keep
|
|
116
120
|
abstract fun exitApp(): Unit
|
|
@@ -196,6 +196,14 @@ namespace margelo::nitro::reactnativedeviceutils {
|
|
|
196
196
|
auto __value = std::move(__result.value());
|
|
197
197
|
return __value;
|
|
198
198
|
}
|
|
199
|
+
inline std::shared_ptr<Promise<std::string>> getAndClearColdStartLocalNotification() override {
|
|
200
|
+
auto __result = _swiftPart.getAndClearColdStartLocalNotification();
|
|
201
|
+
if (__result.hasError()) [[unlikely]] {
|
|
202
|
+
std::rethrow_exception(__result.error());
|
|
203
|
+
}
|
|
204
|
+
auto __value = std::move(__result.value());
|
|
205
|
+
return __value;
|
|
206
|
+
}
|
|
199
207
|
inline void exitApp() override {
|
|
200
208
|
auto __result = _swiftPart.exitApp();
|
|
201
209
|
if (__result.hasError()) [[unlikely]] {
|
|
@@ -29,6 +29,7 @@ public protocol HybridReactNativeDeviceUtilsSpec_protocol: HybridObject {
|
|
|
29
29
|
func saveDeviceToken(token: String) throws -> Promise<Void>
|
|
30
30
|
func registerDeviceToken() throws -> Promise<Bool>
|
|
31
31
|
func getStartupTime() throws -> Promise<Double>
|
|
32
|
+
func getAndClearColdStartLocalNotification() throws -> Promise<String>
|
|
32
33
|
func exitApp() throws -> Void
|
|
33
34
|
func getCurrentWebViewPackageInfo() throws -> Promise<WebViewPackageInfo>
|
|
34
35
|
func isGooglePlayServicesAvailable() throws -> Promise<GooglePlayServicesStatus>
|
|
@@ -360,6 +360,25 @@ open class HybridReactNativeDeviceUtilsSpec_cxx {
|
|
|
360
360
|
}
|
|
361
361
|
}
|
|
362
362
|
|
|
363
|
+
@inline(__always)
|
|
364
|
+
public final func getAndClearColdStartLocalNotification() -> bridge.Result_std__shared_ptr_Promise_std__string___ {
|
|
365
|
+
do {
|
|
366
|
+
let __result = try self.__implementation.getAndClearColdStartLocalNotification()
|
|
367
|
+
let __resultCpp = { () -> bridge.std__shared_ptr_Promise_std__string__ in
|
|
368
|
+
let __promise = bridge.create_std__shared_ptr_Promise_std__string__()
|
|
369
|
+
let __promiseHolder = bridge.wrap_std__shared_ptr_Promise_std__string__(__promise)
|
|
370
|
+
__result
|
|
371
|
+
.then({ __result in __promiseHolder.resolve(std.string(__result)) })
|
|
372
|
+
.catch({ __error in __promiseHolder.reject(__error.toCpp()) })
|
|
373
|
+
return __promise
|
|
374
|
+
}()
|
|
375
|
+
return bridge.create_Result_std__shared_ptr_Promise_std__string___(__resultCpp)
|
|
376
|
+
} catch (let __error) {
|
|
377
|
+
let __exceptionPtr = __error.toCpp()
|
|
378
|
+
return bridge.create_Result_std__shared_ptr_Promise_std__string___(__exceptionPtr)
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
363
382
|
@inline(__always)
|
|
364
383
|
public final func exitApp() -> bridge.Result_void_ {
|
|
365
384
|
do {
|
|
@@ -29,6 +29,7 @@ namespace margelo::nitro::reactnativedeviceutils {
|
|
|
29
29
|
prototype.registerHybridMethod("saveDeviceToken", &HybridReactNativeDeviceUtilsSpec::saveDeviceToken);
|
|
30
30
|
prototype.registerHybridMethod("registerDeviceToken", &HybridReactNativeDeviceUtilsSpec::registerDeviceToken);
|
|
31
31
|
prototype.registerHybridMethod("getStartupTime", &HybridReactNativeDeviceUtilsSpec::getStartupTime);
|
|
32
|
+
prototype.registerHybridMethod("getAndClearColdStartLocalNotification", &HybridReactNativeDeviceUtilsSpec::getAndClearColdStartLocalNotification);
|
|
32
33
|
prototype.registerHybridMethod("exitApp", &HybridReactNativeDeviceUtilsSpec::exitApp);
|
|
33
34
|
prototype.registerHybridMethod("getCurrentWebViewPackageInfo", &HybridReactNativeDeviceUtilsSpec::getCurrentWebViewPackageInfo);
|
|
34
35
|
prototype.registerHybridMethod("isGooglePlayServicesAvailable", &HybridReactNativeDeviceUtilsSpec::isGooglePlayServicesAvailable);
|
|
@@ -86,6 +86,7 @@ namespace margelo::nitro::reactnativedeviceutils {
|
|
|
86
86
|
virtual std::shared_ptr<Promise<void>> saveDeviceToken(const std::string& token) = 0;
|
|
87
87
|
virtual std::shared_ptr<Promise<bool>> registerDeviceToken() = 0;
|
|
88
88
|
virtual std::shared_ptr<Promise<double>> getStartupTime() = 0;
|
|
89
|
+
virtual std::shared_ptr<Promise<std::string>> getAndClearColdStartLocalNotification() = 0;
|
|
89
90
|
virtual void exitApp() = 0;
|
|
90
91
|
virtual std::shared_ptr<Promise<WebViewPackageInfo>> getCurrentWebViewPackageInfo() = 0;
|
|
91
92
|
virtual std::shared_ptr<Promise<GooglePlayServicesStatus>> isGooglePlayServicesAvailable() = 0;
|
package/package.json
CHANGED
|
@@ -59,6 +59,10 @@ export interface ReactNativeDeviceUtils
|
|
|
59
59
|
saveDeviceToken(token: string): Promise<void>;
|
|
60
60
|
registerDeviceToken(): Promise<boolean>;
|
|
61
61
|
getStartupTime(): Promise<number>;
|
|
62
|
+
// Returns the JSON userInfo of a LOCAL notification the user tapped to launch
|
|
63
|
+
// the (killed) app, then clears it so it is delivered exactly once. Empty
|
|
64
|
+
// string when there is none. iOS-only meaningful; Android returns "".
|
|
65
|
+
getAndClearColdStartLocalNotification(): Promise<string>;
|
|
62
66
|
|
|
63
67
|
// ExitModule
|
|
64
68
|
exitApp(): void;
|