@amplytools/react-native-amply-sdk 0.2.3 → 0.2.5
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/build.gradle +89 -0
- package/android/src/main/java/tools/amply/sdk/reactnative/AmplyModule.kt +29 -0
- package/android/src/main/java/tools/amply/sdk/reactnative/core/AmplyClient.kt +6 -0
- package/android/src/main/java/tools/amply/sdk/reactnative/core/DefaultAmplyClient.kt +74 -2
- package/android/src/newarch/java/tools/amply/sdk/reactnative/NativeAmplyModuleSpec.java +18 -1
- package/android/src/newarch/jni/AmplyReactNative-generated.cpp +24 -0
- package/dist/src/__tests__/index.test.js +37 -0
- package/dist/src/index.d.ts +35 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +44 -0
- package/dist/src/nativeSpecs/NativeAmplyModule.d.ts +20 -0
- package/dist/src/nativeSpecs/NativeAmplyModule.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/ARCHITECTURE.md +77 -16
- package/ios/AmplyReactNative.podspec +1 -1
- package/ios/Sources/AmplyReactNative/AmplyModule.mm +93 -0
- package/ios/Sources/AmplyReactNative/AmplyReactNative/AmplyReactNative/AmplyReactNative-generated.mm +160 -0
- package/ios/Sources/AmplyReactNative/AmplyReactNative/AmplyReactNative/AmplyReactNative.h +173 -0
- package/ios/Sources/AmplyReactNative/AmplyReactNative/AmplyReactNative-generated.mm +36 -8
- package/ios/Sources/AmplyReactNative/AmplyReactNative/AmplyReactNative.h +6 -0
- package/package.json +1 -1
- package/src/__tests__/index.test.ts +51 -0
- package/src/index.ts +53 -0
- package/src/nativeSpecs/NativeAmplyModule.ts +20 -0
|
@@ -51,6 +51,7 @@ static NSString* AmplyLogLevelToString(AmplyLogLevel level) {
|
|
|
51
51
|
@property (nonatomic, assign) BOOL lifecycleObserversRegistered;
|
|
52
52
|
@property (nonatomic, assign) BOOL logListenerRegistered;
|
|
53
53
|
@property (nonatomic, assign) AmplyLogLevel currentLogLevel;
|
|
54
|
+
@property (nonatomic, strong) NSMutableArray<void (^)(ASDKAmply *)> *pendingPropertyOps;
|
|
54
55
|
@end
|
|
55
56
|
|
|
56
57
|
@implementation Amply
|
|
@@ -137,6 +138,15 @@ RCT_EXPORT_MODULE()
|
|
|
137
138
|
// Register for app lifecycle notifications to manage session state
|
|
138
139
|
[self registerLifecycleObservers];
|
|
139
140
|
|
|
141
|
+
// Drain buffered property operations
|
|
142
|
+
if (self.pendingPropertyOps.count > 0) {
|
|
143
|
+
RCTLogInfo(@"[AmplyReactNative] Draining %lu buffered property operations", (unsigned long)self.pendingPropertyOps.count);
|
|
144
|
+
for (void (^op)(ASDKAmply *) in self.pendingPropertyOps) {
|
|
145
|
+
op(self.amplyInstance);
|
|
146
|
+
}
|
|
147
|
+
[self.pendingPropertyOps removeAllObjects];
|
|
148
|
+
}
|
|
149
|
+
|
|
140
150
|
RCTLogInfo(@"[AmplyReactNative] Initialized with appId=%@", appId);
|
|
141
151
|
|
|
142
152
|
if (resolve) {
|
|
@@ -383,6 +393,89 @@ RCT_EXPORT_MODULE()
|
|
|
383
393
|
return YES; // Tell SDK we handled it
|
|
384
394
|
}
|
|
385
395
|
|
|
396
|
+
- (void)setCustomProperties:(NSDictionary *)properties
|
|
397
|
+
{
|
|
398
|
+
void (^apply)(ASDKAmply *) = ^(ASDKAmply *instance) {
|
|
399
|
+
for (NSString *key in properties) {
|
|
400
|
+
id value = properties[key];
|
|
401
|
+
if (value && ![value isKindOfClass:[NSNull class]]) {
|
|
402
|
+
[instance setCustomPropertyKey:key value:value];
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
RCTLogInfo(@"[AmplyReactNative] Custom properties set: %@", [properties allKeys]);
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
if (self.amplyInstance) {
|
|
409
|
+
apply(self.amplyInstance);
|
|
410
|
+
} else {
|
|
411
|
+
RCTLogInfo(@"[AmplyReactNative] Buffering setCustomProperties until init: %@", [properties allKeys]);
|
|
412
|
+
if (!self.pendingPropertyOps) self.pendingPropertyOps = [NSMutableArray new];
|
|
413
|
+
[self.pendingPropertyOps addObject:apply];
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
- (void)getCustomProperty:(NSString *)key
|
|
418
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
419
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
420
|
+
{
|
|
421
|
+
if (!self.amplyInstance) {
|
|
422
|
+
if (reject) {
|
|
423
|
+
reject(@"AMP_NOT_INITIALIZED", @"Amply has not been initialized yet", nil);
|
|
424
|
+
}
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
[self.amplyInstance getCustomPropertyKey:key completionHandler:^(id _Nullable_result value, NSError * _Nullable error) {
|
|
429
|
+
if (error) {
|
|
430
|
+
if (reject) {
|
|
431
|
+
reject(@"AMP_CUSTOM_PROP_FAILED", error.localizedDescription, error);
|
|
432
|
+
}
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
NSMutableDictionary *result = [NSMutableDictionary dictionary];
|
|
437
|
+
if (value && ![value isKindOfClass:[NSNull class]]) {
|
|
438
|
+
result[@"value"] = value;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
if (resolve) {
|
|
442
|
+
resolve(result);
|
|
443
|
+
}
|
|
444
|
+
}];
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
- (void)removeCustomProperty:(NSString *)key
|
|
448
|
+
{
|
|
449
|
+
void (^apply)(ASDKAmply *) = ^(ASDKAmply *instance) {
|
|
450
|
+
[instance removeCustomPropertyKey:key];
|
|
451
|
+
RCTLogInfo(@"[AmplyReactNative] Custom property removed: %@", key);
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
if (self.amplyInstance) {
|
|
455
|
+
apply(self.amplyInstance);
|
|
456
|
+
} else {
|
|
457
|
+
RCTLogInfo(@"[AmplyReactNative] Buffering removeCustomProperty until init: %@", key);
|
|
458
|
+
if (!self.pendingPropertyOps) self.pendingPropertyOps = [NSMutableArray new];
|
|
459
|
+
[self.pendingPropertyOps addObject:apply];
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
- (void)clearCustomProperties
|
|
464
|
+
{
|
|
465
|
+
void (^apply)(ASDKAmply *) = ^(ASDKAmply *instance) {
|
|
466
|
+
[instance clearCustomProperties];
|
|
467
|
+
RCTLogInfo(@"[AmplyReactNative] All custom properties cleared");
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
if (self.amplyInstance) {
|
|
471
|
+
apply(self.amplyInstance);
|
|
472
|
+
} else {
|
|
473
|
+
RCTLogInfo(@"[AmplyReactNative] Buffering clearCustomProperties until init");
|
|
474
|
+
if (!self.pendingPropertyOps) self.pendingPropertyOps = [NSMutableArray new];
|
|
475
|
+
[self.pendingPropertyOps addObject:apply];
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
386
479
|
- (void)addListener:(NSString *)eventName
|
|
387
480
|
{
|
|
388
481
|
// Required by RN EventEmitter contracts.
|
package/ios/Sources/AmplyReactNative/AmplyReactNative/AmplyReactNative/AmplyReactNative-generated.mm
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
|
3
|
+
*
|
|
4
|
+
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
|
5
|
+
* once the code is regenerated.
|
|
6
|
+
*
|
|
7
|
+
* @generated by codegen project: GenerateModuleObjCpp
|
|
8
|
+
*
|
|
9
|
+
* We create an umbrella header (and corresponding implementation) here since
|
|
10
|
+
* Cxx compilation in BUCK has a limitation: source-code producing genrule()s
|
|
11
|
+
* must have a single output. More files => more genrule()s => slower builds.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
#import "AmplyReactNative.h"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@implementation NativeAmplyModuleSpecBase
|
|
18
|
+
- (void)emitOnSystemEvent:(NSDictionary *)value
|
|
19
|
+
{
|
|
20
|
+
_eventEmitterCallback("onSystemEvent", value);
|
|
21
|
+
}
|
|
22
|
+
- (void)emitOnDeepLink:(NSDictionary *)value
|
|
23
|
+
{
|
|
24
|
+
_eventEmitterCallback("onDeepLink", value);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
- (void)setEventEmitterCallback:(EventEmitterCallbackWrapper *)eventEmitterCallbackWrapper
|
|
28
|
+
{
|
|
29
|
+
_eventEmitterCallback = std::move(eventEmitterCallbackWrapper->_eventEmitterCallback);
|
|
30
|
+
}
|
|
31
|
+
@end
|
|
32
|
+
|
|
33
|
+
@implementation RCTCxxConvert (NativeAmplyModule_AmplyInitializationConfig)
|
|
34
|
+
+ (RCTManagedPointer *)JS_NativeAmplyModule_AmplyInitializationConfig:(id)json
|
|
35
|
+
{
|
|
36
|
+
return facebook::react::managedPointer<JS::NativeAmplyModule::AmplyInitializationConfig>(json);
|
|
37
|
+
}
|
|
38
|
+
@end
|
|
39
|
+
@implementation RCTCxxConvert (NativeAmplyModule_TrackEventPayload)
|
|
40
|
+
+ (RCTManagedPointer *)JS_NativeAmplyModule_TrackEventPayload:(id)json
|
|
41
|
+
{
|
|
42
|
+
return facebook::react::managedPointer<JS::NativeAmplyModule::TrackEventPayload>(json);
|
|
43
|
+
}
|
|
44
|
+
@end
|
|
45
|
+
namespace facebook::react {
|
|
46
|
+
|
|
47
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_initialize(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
48
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "initialize", @selector(initialize:resolve:reject:), args, count);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_isInitialized(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
52
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, BooleanKind, "isInitialized", @selector(isInitialized), args, count);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_track(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
56
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "track", @selector(track:resolve:reject:), args, count);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_getRecentEvents(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
60
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "getRecentEvents", @selector(getRecentEvents:resolve:reject:), args, count);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_getDataSetSnapshot(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
64
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "getDataSetSnapshot", @selector(getDataSetSnapshot:resolve:reject:), args, count);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_registerDeepLinkListener(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
68
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "registerDeepLinkListener", @selector(registerDeepLinkListener), args, count);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_setUserId(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
72
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "setUserId", @selector(setUserId:), args, count);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_setLogLevel(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
76
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "setLogLevel", @selector(setLogLevel:), args, count);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_getLogLevel(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
80
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, StringKind, "getLogLevel", @selector(getLogLevel), args, count);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_setCustomProperties(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
84
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "setCustomProperties", @selector(setCustomProperties:), args, count);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_getCustomProperty(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
88
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "getCustomProperty", @selector(getCustomProperty:resolve:reject:), args, count);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_removeCustomProperty(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
92
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "removeCustomProperty", @selector(removeCustomProperty:), args, count);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_clearCustomProperties(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
96
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "clearCustomProperties", @selector(clearCustomProperties), args, count);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_addListener(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
100
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "addListener", @selector(addListener:), args, count);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_removeListeners(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
104
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "removeListeners", @selector(removeListeners:), args, count);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
NativeAmplyModuleSpecJSI::NativeAmplyModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms)
|
|
108
|
+
: ObjCTurboModule(params) {
|
|
109
|
+
|
|
110
|
+
methodMap_["initialize"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_initialize};
|
|
111
|
+
setMethodArgConversionSelector(@"initialize", 0, @"JS_NativeAmplyModule_AmplyInitializationConfig:");
|
|
112
|
+
|
|
113
|
+
methodMap_["isInitialized"] = MethodMetadata {0, __hostFunction_NativeAmplyModuleSpecJSI_isInitialized};
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
methodMap_["track"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_track};
|
|
117
|
+
setMethodArgConversionSelector(@"track", 0, @"JS_NativeAmplyModule_TrackEventPayload:");
|
|
118
|
+
|
|
119
|
+
methodMap_["getRecentEvents"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_getRecentEvents};
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
methodMap_["getDataSetSnapshot"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_getDataSetSnapshot};
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
methodMap_["registerDeepLinkListener"] = MethodMetadata {0, __hostFunction_NativeAmplyModuleSpecJSI_registerDeepLinkListener};
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
methodMap_["setUserId"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_setUserId};
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
methodMap_["setLogLevel"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_setLogLevel};
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
methodMap_["getLogLevel"] = MethodMetadata {0, __hostFunction_NativeAmplyModuleSpecJSI_getLogLevel};
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
methodMap_["setCustomProperties"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_setCustomProperties};
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
methodMap_["getCustomProperty"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_getCustomProperty};
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
methodMap_["removeCustomProperty"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_removeCustomProperty};
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
methodMap_["clearCustomProperties"] = MethodMetadata {0, __hostFunction_NativeAmplyModuleSpecJSI_clearCustomProperties};
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
methodMap_["addListener"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_addListener};
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
methodMap_["removeListeners"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_removeListeners};
|
|
153
|
+
|
|
154
|
+
eventEmitterMap_["onSystemEvent"] = std::make_shared<AsyncEventEmitter<id>>();
|
|
155
|
+
eventEmitterMap_["onDeepLink"] = std::make_shared<AsyncEventEmitter<id>>();
|
|
156
|
+
setEventEmitterCallback([&](const std::string &name, id value) {
|
|
157
|
+
static_cast<AsyncEventEmitter<id> &>(*eventEmitterMap_[name]).emit(value);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
|
3
|
+
*
|
|
4
|
+
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
|
5
|
+
* once the code is regenerated.
|
|
6
|
+
*
|
|
7
|
+
* @generated by codegen project: GenerateModuleObjCpp
|
|
8
|
+
*
|
|
9
|
+
* We create an umbrella header (and corresponding implementation) here since
|
|
10
|
+
* Cxx compilation in BUCK has a limitation: source-code producing genrule()s
|
|
11
|
+
* must have a single output. More files => more genrule()s => slower builds.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
#ifndef __cplusplus
|
|
15
|
+
#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm.
|
|
16
|
+
#endif
|
|
17
|
+
|
|
18
|
+
// Avoid multiple includes of AmplyReactNative symbols
|
|
19
|
+
#ifndef AmplyReactNative_H
|
|
20
|
+
#define AmplyReactNative_H
|
|
21
|
+
|
|
22
|
+
#import <Foundation/Foundation.h>
|
|
23
|
+
#import <RCTRequired/RCTRequired.h>
|
|
24
|
+
#import <RCTTypeSafety/RCTConvertHelpers.h>
|
|
25
|
+
#import <RCTTypeSafety/RCTTypedModuleConstants.h>
|
|
26
|
+
#import <React/RCTBridgeModule.h>
|
|
27
|
+
#import <React/RCTCxxConvert.h>
|
|
28
|
+
#import <React/RCTManagedPointer.h>
|
|
29
|
+
#import <ReactCommon/RCTTurboModule.h>
|
|
30
|
+
#import <optional>
|
|
31
|
+
#import <vector>
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
35
|
+
namespace JS {
|
|
36
|
+
namespace NativeAmplyModule {
|
|
37
|
+
struct AmplyInitializationConfig {
|
|
38
|
+
NSString *appId() const;
|
|
39
|
+
NSString *apiKeyPublic() const;
|
|
40
|
+
NSString *apiKeySecret() const;
|
|
41
|
+
NSString *endpoint() const;
|
|
42
|
+
id<NSObject> _Nullable datasetPrefetch() const;
|
|
43
|
+
NSString *defaultConfig() const;
|
|
44
|
+
std::optional<bool> debug() const;
|
|
45
|
+
NSString *logLevel() const;
|
|
46
|
+
|
|
47
|
+
AmplyInitializationConfig(NSDictionary *const v) : _v(v) {}
|
|
48
|
+
private:
|
|
49
|
+
NSDictionary *_v;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@interface RCTCxxConvert (NativeAmplyModule_AmplyInitializationConfig)
|
|
55
|
+
+ (RCTManagedPointer *)JS_NativeAmplyModule_AmplyInitializationConfig:(id)json;
|
|
56
|
+
@end
|
|
57
|
+
namespace JS {
|
|
58
|
+
namespace NativeAmplyModule {
|
|
59
|
+
struct TrackEventPayload {
|
|
60
|
+
NSString *name() const;
|
|
61
|
+
id<NSObject> _Nullable properties() const;
|
|
62
|
+
|
|
63
|
+
TrackEventPayload(NSDictionary *const v) : _v(v) {}
|
|
64
|
+
private:
|
|
65
|
+
NSDictionary *_v;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@interface RCTCxxConvert (NativeAmplyModule_TrackEventPayload)
|
|
71
|
+
+ (RCTManagedPointer *)JS_NativeAmplyModule_TrackEventPayload:(id)json;
|
|
72
|
+
@end
|
|
73
|
+
@protocol NativeAmplyModuleSpec <RCTBridgeModule, RCTTurboModule>
|
|
74
|
+
|
|
75
|
+
- (void)initialize:(JS::NativeAmplyModule::AmplyInitializationConfig &)config
|
|
76
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
77
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
78
|
+
- (NSNumber *)isInitialized;
|
|
79
|
+
- (void)track:(JS::NativeAmplyModule::TrackEventPayload &)payload
|
|
80
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
81
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
82
|
+
- (void)getRecentEvents:(double)limit
|
|
83
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
84
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
85
|
+
- (void)getDataSetSnapshot:(NSDictionary *)type
|
|
86
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
87
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
88
|
+
- (void)registerDeepLinkListener;
|
|
89
|
+
- (void)setUserId:(NSString * _Nullable)userId;
|
|
90
|
+
- (void)setLogLevel:(NSString *)level;
|
|
91
|
+
- (NSString *)getLogLevel;
|
|
92
|
+
- (void)setCustomProperties:(NSDictionary *)properties;
|
|
93
|
+
- (void)getCustomProperty:(NSString *)key
|
|
94
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
95
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
96
|
+
- (void)removeCustomProperty:(NSString *)key;
|
|
97
|
+
- (void)clearCustomProperties;
|
|
98
|
+
- (void)addListener:(NSString *)eventName;
|
|
99
|
+
- (void)removeListeners:(double)count;
|
|
100
|
+
|
|
101
|
+
@end
|
|
102
|
+
|
|
103
|
+
@interface NativeAmplyModuleSpecBase : NSObject {
|
|
104
|
+
@protected
|
|
105
|
+
facebook::react::EventEmitterCallback _eventEmitterCallback;
|
|
106
|
+
}
|
|
107
|
+
- (void)setEventEmitterCallback:(EventEmitterCallbackWrapper *)eventEmitterCallbackWrapper;
|
|
108
|
+
|
|
109
|
+
- (void)emitOnSystemEvent:(NSDictionary *)value;
|
|
110
|
+
- (void)emitOnDeepLink:(NSDictionary *)value;
|
|
111
|
+
@end
|
|
112
|
+
|
|
113
|
+
namespace facebook::react {
|
|
114
|
+
/**
|
|
115
|
+
* ObjC++ class for module 'NativeAmplyModule'
|
|
116
|
+
*/
|
|
117
|
+
class JSI_EXPORT NativeAmplyModuleSpecJSI : public ObjCTurboModule {
|
|
118
|
+
public:
|
|
119
|
+
NativeAmplyModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms);
|
|
120
|
+
};
|
|
121
|
+
} // namespace facebook::react
|
|
122
|
+
inline NSString *JS::NativeAmplyModule::AmplyInitializationConfig::appId() const
|
|
123
|
+
{
|
|
124
|
+
id const p = _v[@"appId"];
|
|
125
|
+
return RCTBridgingToString(p);
|
|
126
|
+
}
|
|
127
|
+
inline NSString *JS::NativeAmplyModule::AmplyInitializationConfig::apiKeyPublic() const
|
|
128
|
+
{
|
|
129
|
+
id const p = _v[@"apiKeyPublic"];
|
|
130
|
+
return RCTBridgingToString(p);
|
|
131
|
+
}
|
|
132
|
+
inline NSString *JS::NativeAmplyModule::AmplyInitializationConfig::apiKeySecret() const
|
|
133
|
+
{
|
|
134
|
+
id const p = _v[@"apiKeySecret"];
|
|
135
|
+
return RCTBridgingToOptionalString(p);
|
|
136
|
+
}
|
|
137
|
+
inline NSString *JS::NativeAmplyModule::AmplyInitializationConfig::endpoint() const
|
|
138
|
+
{
|
|
139
|
+
id const p = _v[@"endpoint"];
|
|
140
|
+
return RCTBridgingToOptionalString(p);
|
|
141
|
+
}
|
|
142
|
+
inline id<NSObject> _Nullable JS::NativeAmplyModule::AmplyInitializationConfig::datasetPrefetch() const
|
|
143
|
+
{
|
|
144
|
+
id const p = _v[@"datasetPrefetch"];
|
|
145
|
+
return p;
|
|
146
|
+
}
|
|
147
|
+
inline NSString *JS::NativeAmplyModule::AmplyInitializationConfig::defaultConfig() const
|
|
148
|
+
{
|
|
149
|
+
id const p = _v[@"defaultConfig"];
|
|
150
|
+
return RCTBridgingToOptionalString(p);
|
|
151
|
+
}
|
|
152
|
+
inline std::optional<bool> JS::NativeAmplyModule::AmplyInitializationConfig::debug() const
|
|
153
|
+
{
|
|
154
|
+
id const p = _v[@"debug"];
|
|
155
|
+
return RCTBridgingToOptionalBool(p);
|
|
156
|
+
}
|
|
157
|
+
inline NSString *JS::NativeAmplyModule::AmplyInitializationConfig::logLevel() const
|
|
158
|
+
{
|
|
159
|
+
id const p = _v[@"logLevel"];
|
|
160
|
+
return RCTBridgingToOptionalString(p);
|
|
161
|
+
}
|
|
162
|
+
inline NSString *JS::NativeAmplyModule::TrackEventPayload::name() const
|
|
163
|
+
{
|
|
164
|
+
id const p = _v[@"name"];
|
|
165
|
+
return RCTBridgingToString(p);
|
|
166
|
+
}
|
|
167
|
+
inline id<NSObject> _Nullable JS::NativeAmplyModule::TrackEventPayload::properties() const
|
|
168
|
+
{
|
|
169
|
+
id const p = _v[@"properties"];
|
|
170
|
+
return p;
|
|
171
|
+
}
|
|
172
|
+
NS_ASSUME_NONNULL_END
|
|
173
|
+
#endif // AmplyReactNative_H
|
|
@@ -80,6 +80,22 @@ namespace facebook::react {
|
|
|
80
80
|
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, StringKind, "getLogLevel", @selector(getLogLevel), args, count);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_setCustomProperties(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
84
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "setCustomProperties", @selector(setCustomProperties:), args, count);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_getCustomProperty(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
88
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "getCustomProperty", @selector(getCustomProperty:resolve:reject:), args, count);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_removeCustomProperty(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
92
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "removeCustomProperty", @selector(removeCustomProperty:), args, count);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_clearCustomProperties(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
96
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "clearCustomProperties", @selector(clearCustomProperties), args, count);
|
|
97
|
+
}
|
|
98
|
+
|
|
83
99
|
static facebook::jsi::Value __hostFunction_NativeAmplyModuleSpecJSI_addListener(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
84
100
|
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "addListener", @selector(addListener:), args, count);
|
|
85
101
|
}
|
|
@@ -107,17 +123,29 @@ namespace facebook::react {
|
|
|
107
123
|
|
|
108
124
|
|
|
109
125
|
methodMap_["registerDeepLinkListener"] = MethodMetadata {0, __hostFunction_NativeAmplyModuleSpecJSI_registerDeepLinkListener};
|
|
110
|
-
|
|
111
|
-
|
|
126
|
+
|
|
127
|
+
|
|
112
128
|
methodMap_["setUserId"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_setUserId};
|
|
113
|
-
|
|
114
|
-
|
|
129
|
+
|
|
130
|
+
|
|
115
131
|
methodMap_["setLogLevel"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_setLogLevel};
|
|
116
|
-
|
|
117
|
-
|
|
132
|
+
|
|
133
|
+
|
|
118
134
|
methodMap_["getLogLevel"] = MethodMetadata {0, __hostFunction_NativeAmplyModuleSpecJSI_getLogLevel};
|
|
119
|
-
|
|
120
|
-
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
methodMap_["setCustomProperties"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_setCustomProperties};
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
methodMap_["getCustomProperty"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_getCustomProperty};
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
methodMap_["removeCustomProperty"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_removeCustomProperty};
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
methodMap_["clearCustomProperties"] = MethodMetadata {0, __hostFunction_NativeAmplyModuleSpecJSI_clearCustomProperties};
|
|
147
|
+
|
|
148
|
+
|
|
121
149
|
methodMap_["addListener"] = MethodMetadata {1, __hostFunction_NativeAmplyModuleSpecJSI_addListener};
|
|
122
150
|
|
|
123
151
|
|
|
@@ -89,6 +89,12 @@ namespace JS {
|
|
|
89
89
|
- (void)setUserId:(NSString * _Nullable)userId;
|
|
90
90
|
- (void)setLogLevel:(NSString *)level;
|
|
91
91
|
- (NSString *)getLogLevel;
|
|
92
|
+
- (void)setCustomProperties:(NSDictionary *)properties;
|
|
93
|
+
- (void)getCustomProperty:(NSString *)key
|
|
94
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
95
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
96
|
+
- (void)removeCustomProperty:(NSString *)key;
|
|
97
|
+
- (void)clearCustomProperties;
|
|
92
98
|
- (void)addListener:(NSString *)eventName;
|
|
93
99
|
- (void)removeListeners:(double)count;
|
|
94
100
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amplytools/react-native-amply-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "React Native SDK for Amply: Mobile SDK to orchestrate in-app experiences and campaigns remotely, without app releases",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -12,6 +12,10 @@ const mockNativeModule = {
|
|
|
12
12
|
removeListeners: jest.fn(),
|
|
13
13
|
onSystemEvent: jest.fn(),
|
|
14
14
|
onDeepLink: jest.fn(),
|
|
15
|
+
setCustomProperties: jest.fn(),
|
|
16
|
+
getCustomProperty: jest.fn(),
|
|
17
|
+
removeCustomProperty: jest.fn(),
|
|
18
|
+
clearCustomProperties: jest.fn(),
|
|
15
19
|
};
|
|
16
20
|
|
|
17
21
|
describe('Amply JS API', () => {
|
|
@@ -87,6 +91,53 @@ describe('Amply JS API', () => {
|
|
|
87
91
|
expect(remove).toHaveBeenCalledTimes(1);
|
|
88
92
|
});
|
|
89
93
|
|
|
94
|
+
it('sets a single custom property via setCustomProperties', () => {
|
|
95
|
+
Amply.setCustomProperty('plan', 'premium');
|
|
96
|
+
|
|
97
|
+
expect(mockNativeModule.setCustomProperties).toHaveBeenCalledWith({
|
|
98
|
+
plan: 'premium',
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('sets multiple custom properties at once', () => {
|
|
103
|
+
Amply.setCustomProperties({ plan: 'premium', age: 25, active: true });
|
|
104
|
+
|
|
105
|
+
expect(mockNativeModule.setCustomProperties).toHaveBeenCalledWith({
|
|
106
|
+
plan: 'premium',
|
|
107
|
+
age: 25,
|
|
108
|
+
active: true,
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('gets a custom property value', async () => {
|
|
113
|
+
mockNativeModule.getCustomProperty.mockResolvedValueOnce({ value: 'premium' });
|
|
114
|
+
|
|
115
|
+
const result = await Amply.getCustomProperty('plan');
|
|
116
|
+
|
|
117
|
+
expect(mockNativeModule.getCustomProperty).toHaveBeenCalledWith('plan');
|
|
118
|
+
expect(result).toBe('premium');
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('returns null for a missing custom property', async () => {
|
|
122
|
+
mockNativeModule.getCustomProperty.mockResolvedValueOnce({});
|
|
123
|
+
|
|
124
|
+
const result = await Amply.getCustomProperty('nonexistent');
|
|
125
|
+
|
|
126
|
+
expect(result).toBeNull();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('removes a custom property', () => {
|
|
130
|
+
Amply.removeCustomProperty('plan');
|
|
131
|
+
|
|
132
|
+
expect(mockNativeModule.removeCustomProperty).toHaveBeenCalledWith('plan');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('clears all custom properties', () => {
|
|
136
|
+
Amply.clearCustomProperties();
|
|
137
|
+
|
|
138
|
+
expect(mockNativeModule.clearCustomProperties).toHaveBeenCalled();
|
|
139
|
+
});
|
|
140
|
+
|
|
90
141
|
it('registers deep links once and subscribes via the TurboModule emitter', async () => {
|
|
91
142
|
const remove = jest.fn();
|
|
92
143
|
mockNativeModule.onDeepLink.mockReturnValue({ remove });
|
package/src/index.ts
CHANGED
|
@@ -154,6 +154,54 @@ export async function addSystemEventListener(
|
|
|
154
154
|
return addSystemEventListenerInternal(listener);
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Custom property value type. Supports string, number, and boolean values.
|
|
159
|
+
*/
|
|
160
|
+
export type CustomPropertyValue = string | number | boolean;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Set a single custom property.
|
|
164
|
+
* @param key The property key (max 32 characters)
|
|
165
|
+
* @param value The property value (string max 255 characters)
|
|
166
|
+
*/
|
|
167
|
+
export function setCustomProperty(key: string, value: CustomPropertyValue): void {
|
|
168
|
+
getNativeModule().setCustomProperties({[key]: value});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Set multiple custom properties at once.
|
|
173
|
+
* @param properties Key-value map of properties to set
|
|
174
|
+
*/
|
|
175
|
+
export function setCustomProperties(properties: Record<string, CustomPropertyValue>): void {
|
|
176
|
+
getNativeModule().setCustomProperties(properties);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Get a custom property value by key.
|
|
181
|
+
* @param key The property key
|
|
182
|
+
* @returns The property value, or null if not found
|
|
183
|
+
*/
|
|
184
|
+
export async function getCustomProperty(key: string): Promise<CustomPropertyValue | null> {
|
|
185
|
+
const result = await getNativeModule().getCustomProperty(key);
|
|
186
|
+
const map = result as {value?: unknown};
|
|
187
|
+
return (map.value as CustomPropertyValue) ?? null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Remove a custom property by key.
|
|
192
|
+
* @param key The property key to remove
|
|
193
|
+
*/
|
|
194
|
+
export function removeCustomProperty(key: string): void {
|
|
195
|
+
getNativeModule().removeCustomProperty(key);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Remove all custom properties.
|
|
200
|
+
*/
|
|
201
|
+
export function clearCustomProperties(): void {
|
|
202
|
+
getNativeModule().clearCustomProperties();
|
|
203
|
+
}
|
|
204
|
+
|
|
157
205
|
export function removeAllListeners(): void {
|
|
158
206
|
deepLinkSubscriptions.forEach(unsubscribe => {
|
|
159
207
|
try {
|
|
@@ -198,5 +246,10 @@ export default {
|
|
|
198
246
|
setUserId,
|
|
199
247
|
setLogLevel,
|
|
200
248
|
getLogLevel,
|
|
249
|
+
setCustomProperty,
|
|
250
|
+
setCustomProperties,
|
|
251
|
+
getCustomProperty,
|
|
252
|
+
removeCustomProperty,
|
|
253
|
+
clearCustomProperties,
|
|
201
254
|
systemEvents,
|
|
202
255
|
};
|