@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.
@@ -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.
@@ -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 &params)
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 &params);
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",
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
  };