react-native-nami-sdk 2.0.5 → 3.0.9

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.
Files changed (56) hide show
  1. package/.github/workflows/app_stg.yaml +203 -0
  2. package/.pre-commit-config.yaml +1 -1
  3. package/android/build.gradle +24 -13
  4. package/android/gradle/wrapper/gradle-wrapper.properties +5 -1
  5. package/android/src/main/java/com/nami/reactlibrary/NamiBridgeModule.kt +7 -51
  6. package/android/src/main/java/com/nami/reactlibrary/NamiBridgePackage.java +1 -0
  7. package/android/src/main/java/com/nami/reactlibrary/NamiCampaignManagerBridge.kt +136 -0
  8. package/android/src/main/java/com/nami/reactlibrary/NamiCustomerManagerBridge.kt +97 -18
  9. package/android/src/main/java/com/nami/reactlibrary/NamiEmitter.kt +24 -24
  10. package/android/src/main/java/com/nami/reactlibrary/NamiEntitlementManagerBridgeModule.kt +30 -129
  11. package/android/src/main/java/com/nami/reactlibrary/NamiPaywallManagerBridgeModule.kt +133 -149
  12. package/android/src/main/java/com/nami/reactlibrary/NamiPurchaseManagerBridge.kt +36 -38
  13. package/android/src/main/java/com/nami/reactlibrary/NamiUtil.kt +50 -180
  14. package/build-utils/get_version_code.py +140 -0
  15. package/index.d.ts +20 -0
  16. package/index.js +7 -6
  17. package/ios/Nami.m +9 -63
  18. package/ios/NamiBridgeUtil.h +4 -6
  19. package/ios/NamiBridgeUtil.m +16 -78
  20. package/ios/NamiCampaignManagerBridge.m +26 -0
  21. package/ios/NamiCampaignManagerBridge.swift +112 -0
  22. package/ios/NamiCustomerManager.m +22 -23
  23. package/ios/NamiCustomerManager.swift +132 -0
  24. package/ios/NamiEmitter.m +55 -65
  25. package/ios/NamiEntitlementManagerBridge.m +7 -107
  26. package/ios/NamiEntitlementManagerBridge.swift +74 -0
  27. package/ios/NamiMLManagerBridge.m +2 -2
  28. package/ios/NamiPaywallManagerBridge.m +22 -94
  29. package/ios/NamiPaywallManagerBridge.swift +93 -0
  30. package/ios/NamiPurchaseManagerBridge.m +38 -69
  31. package/ios/NamiPurchaseManagerBridge.swift +174 -0
  32. package/ios/Podfile +2 -2
  33. package/ios/RNNami-Bridging-Header.h +5 -0
  34. package/ios/RNNami.h +0 -1
  35. package/ios/RNNami.m +1 -1
  36. package/ios/RNNami.xcodeproj/project.pbxproj +83 -11
  37. package/ios/RNNami.xcodeproj/xcshareddata/xcschemes/RNNami.xcscheme +67 -0
  38. package/package.json +1 -1
  39. package/react-native-nami-sdk.podspec +3 -3
  40. package/src/Nami.d.ts +112 -0
  41. package/src/Nami.js +10 -0
  42. package/src/NamiCampaignManager.d.ts +57 -0
  43. package/src/NamiCampaignManager.js +54 -0
  44. package/src/NamiCustomerManager.d.ts +41 -0
  45. package/src/NamiCustomerManager.js +43 -0
  46. package/src/NamiEntitlementManager.d.ts +24 -0
  47. package/src/NamiEntitlementManager.js +23 -0
  48. package/src/NamiMLManager.d.ts +5 -0
  49. package/src/NamiMLManager.js +7 -0
  50. package/src/NamiPaywallManager.d.ts +82 -0
  51. package/src/NamiPaywallManager.js +37 -0
  52. package/src/NamiPurchaseManager.d.ts +57 -0
  53. package/src/NamiPurchaseManager.js +37 -0
  54. package/src/types.ts +36 -0
  55. package/android/src/main/java/com/nami/reactlibrary/NamiAnalyticsEmitter.kt +0 -121
  56. package/ios/NamiAnalyticsEmitter.m +0 -146
package/ios/NamiEmitter.m CHANGED
@@ -2,13 +2,12 @@
2
2
  // NamiEmitter.m
3
3
  // namiReactNative
4
4
  //
5
- // Created by Kendall Helmstetter Gelner on 12/11/19.
6
5
  // Copyright © 2019 Nami ML Inc. All rights reserved.
7
6
  //
8
7
 
9
8
  #import <Foundation/Foundation.h>
10
9
 
11
- #import <Nami/Nami.h>
10
+ #import <NamiApple/NamiApple.h>
12
11
 
13
12
  #import <React/RCTBridgeModule.h>
14
13
  #import <React/RCTEventEmitter.h>
@@ -38,31 +37,25 @@ static NamiEmitter *namiEmitter;
38
37
  [self sendEventPurchaseMadeWithPurchases:purchases withState:purchaseState error:error];
39
38
  }];
40
39
 
41
- [NamiEntitlementManager registerEntitlementsChangedHandler:^(NSArray<NamiEntitlement *> * _Nonnull entitlements) {
40
+ [NamiEntitlementManager registerActiveEntitlementsHandler:^(NSArray<NamiEntitlement *> * _Nonnull entitlements) {
42
41
  [self sendEventEntitlementsChangedWithEntitlements:entitlements];
43
42
  }];
44
43
 
45
-
46
- [NamiPaywallManager registerSignInHandler:^(UIViewController * _Nullable fromVC, NSString * _Nonnull developerPaywallID, NamiPaywall * _Nonnull paywallMetadata) {
47
- [self sendSignInActivateFromVC:fromVC forPaywall:developerPaywallID paywallMetadata:paywallMetadata];
48
- }];
49
-
50
- [NamiPaywallManager registerPaywallRaiseHandler:^(UIViewController * _Nullable fromVC, NSArray<NamiSKU *> * _Nullable products, NSString * _Nonnull developerPaywallID, NamiPaywall * _Nonnull paywallMetadata) {
51
- [self sendPaywallActivatedFromVC:fromVC forPaywall:developerPaywallID withProducts:products paywallMetadata:paywallMetadata];
44
+ [NamiPaywallManager registerSignInHandler:^(UIViewController * _Nullable fromVC) {
45
+ [self sendSignInActivateFromVC:fromVC];
52
46
  }];
53
47
 
54
- [NamiPaywallManager registerBlockingPaywallClosedHandler:^{
55
- [self sendBlockingPaywallClosed];
56
- }];
48
+ // [NamiPaywallManager registerCloseHandler:^(UIViewController * _Nullable fromVC) {
49
+ // [self sendBlockingPaywallClosed];
50
+ // }];
57
51
 
58
52
  [NamiPurchaseManager registerRestorePurchasesHandlerWithRestorePurchasesStateHandler:^(enum NamiRestorePurchasesState state, NSArray<NamiPurchase *> * _Nonnull newPurchases, NSArray<NamiPurchase *> * _Nonnull oldPurchases, NSError * _Nullable error) {
59
53
  [self sendRestorePurchasesStateChanged:state newPurchases:newPurchases oldPurchases:oldPurchases error:error];
60
54
  }];
61
55
 
62
- [NamiCustomerManager registerJourneyStateChangedHandler:^(CustomerJourneyState * _Nonnull journeyState) {
56
+ [NamiCustomerManager registerJourneyStateHandler:^(CustomerJourneyState * _Nonnull journeyState) {
63
57
  [self sendEventCustomerJourneyStateChanged:journeyState];
64
58
  }];
65
-
66
59
  }
67
60
  namiEmitter = self;
68
61
  return self;
@@ -86,7 +79,7 @@ static NamiEmitter *namiEmitter;
86
79
  NSArray<NamiPurchase *> *purchases = NamiPurchaseManager.allPurchases;
87
80
  NSMutableArray<NSString *> *productIDs = [NSMutableArray new];
88
81
  for (NamiPurchase *purchase in purchases) {
89
- [productIDs addObject:purchase.skuID];
82
+ [productIDs addObject:purchase.skuId];
90
83
  }
91
84
 
92
85
  return productIDs;
@@ -157,7 +150,7 @@ bool hasNamiEmitterListeners;
157
150
 
158
151
  NSMutableArray *convertedEntitlementDicts = [NSMutableArray new];
159
152
  for ( NamiEntitlement *entitlementRecord in entitlements ) {
160
- if ( entitlementRecord.referenceID != nil ) {
153
+ if ( entitlementRecord.referenceId != nil ) {
161
154
  NSDictionary *entitlementDict = [NamiBridgeUtil entitlementToEntitlementDict:entitlementRecord];
162
155
  [convertedEntitlementDicts addObject:entitlementDict];
163
156
  }
@@ -209,7 +202,7 @@ bool hasNamiEmitterListeners;
209
202
 
210
203
  NSMutableArray *convertedPurchaseDicts = [NSMutableArray new];
211
204
  for ( NamiPurchase *purchaseRecord in purchases ) {
212
- if ( purchaseRecord.skuID != nil ) {
205
+ if ( purchaseRecord.skuId != nil ) {
213
206
  NSDictionary *purchaseDict = [NamiBridgeUtil purchaseToPurchaseDict:purchaseRecord];
214
207
  [convertedPurchaseDicts addObject:purchaseDict];
215
208
  }
@@ -229,56 +222,53 @@ bool hasNamiEmitterListeners;
229
222
  }
230
223
 
231
224
 
232
- - (void) sendSignInActivateFromVC:(UIViewController * _Nullable) fromVC
233
- forPaywall:(NSString * _Nonnull) developerPaywallID
234
- paywallMetadata:(NamiPaywall * _Nonnull) paywallMetadata {
225
+ - (void) sendSignInActivateFromVC:(UIViewController * _Nullable) fromVC {
235
226
  if (hasNamiEmitterListeners) {
236
227
  // Pass along paywall ID use in sign-in provider.
237
- [self sendEventWithName:@"SignInActivate" body:@{ @"developerPaywallID": developerPaywallID }];
228
+ [self sendEventWithName:@"SignInActivate" body:@{ }];
238
229
  }
239
230
  }
240
231
 
241
- - (void)sendPaywallActivatedFromVC:(UIViewController * _Nullable) fromVC
242
- forPaywall:(NSString * _Nonnull) developerPaywallID
243
- withProducts:(NSArray<NamiSKU *> * _Nullable) products
244
- paywallMetadata:(NamiPaywall * _Nonnull) paywallMetadata {
245
- if (hasNamiEmitterListeners) {
246
- NSMutableArray<NSDictionary<NSString *,NSString *> *> *skuDicts = [NSMutableArray new];
247
- for (NamiSKU *sku in products) {
248
- [skuDicts addObject:[NamiBridgeUtil skuToSKUDict:sku]];
249
- }
250
-
251
- NSMutableDictionary *paywallMeta = [NSMutableDictionary dictionaryWithDictionary:paywallMetadata.namiPaywallInfoDict];
252
- // This part is really meant to be internally facing, scrub from dictionary
253
-
254
- NSMutableDictionary *marketingContentDictionary = [NSMutableDictionary dictionaryWithDictionary:paywallMeta[@"marketing_content"]];
255
-
256
- // Populated SmartText formatted values in dictioanry to send
257
- marketingContentDictionary[@"body"] = [paywallMetadata body];
258
- marketingContentDictionary[@"title"] = [paywallMetadata title];
259
- paywallMeta[@"marketing_content"] = marketingContentDictionary;
260
- paywallMeta[@"purchase_terms"] = [paywallMetadata purchaseTerms];
261
-
262
- // Strip out presention_position from all listed sku items
263
- NSArray *cleanedOrderdMetadata = [NamiBridgeUtil stripPresentationPositionFromOrderedMetadataForPaywallMetaDict:paywallMeta];
264
- [paywallMeta setObject:cleanedOrderdMetadata forKey:@"formatted_skus"];
265
-
266
- [paywallMeta removeObjectForKey:@"sku_ordered_metadata"];
267
- [paywallMeta removeObjectForKey:@"skus"];
268
-
269
- NSDictionary *paywallStylingDict = [NamiBridgeUtil paywallStylingToPaywallStylingDict:[paywallMetadata styleData]];
270
- paywallMeta[@"styleData"] = paywallStylingDict;
271
-
272
- // remove keys that are inconsistent with android
273
- [paywallMeta removeObjectForKey:@"body"];
274
- [paywallMeta removeObjectForKey:@"title"];
275
- [paywallMeta removeObjectForKey:@"style"];
276
-
277
- [self sendEventWithName:@"AppPaywallActivate" body:@{ @"namiSkus": skuDicts,
278
- @"developerPaywallID": developerPaywallID,
279
- @"paywallMetadata": paywallMeta }];
280
- }
281
- }
232
+ //- (void)sendPaywallActivatedForPaywall:(NSString * _Nonnull) developerPaywallID
233
+ // withProducts:(NSArray<NamiSKU *> * _Nullable) products
234
+ // paywallMetadata:(NamiPaywall * _Nonnull) paywallMetadata {
235
+ // if (hasNamiEmitterListeners) {
236
+ // NSMutableArray<NSDictionary<NSString *,NSString *> *> *skuDicts = [NSMutableArray new];
237
+ // for (NamiSKU *sku in products) {
238
+ // [skuDicts addObject:[NamiBridgeUtil skuToSKUDict:sku]];
239
+ // }
240
+ //
241
+ // NSMutableDictionary *paywallMeta = [NSMutableDictionary dictionaryWithDictionary:paywallMetadata.namiPaywallInfoDict];
242
+ // // This part is really meant to be internally facing, scrub from dictionary
243
+ //
244
+ // NSMutableDictionary *marketingContentDictionary = [NSMutableDictionary dictionaryWithDictionary:paywallMeta[@"marketing_content"]];
245
+ //
246
+ // // Populated SmartText formatted values in dictioanry to send
247
+ // marketingContentDictionary[@"body"] = [paywallMetadata body];
248
+ // marketingContentDictionary[@"title"] = [paywallMetadata title];
249
+ // paywallMeta[@"marketing_content"] = marketingContentDictionary;
250
+ // paywallMeta[@"purchase_terms"] = [paywallMetadata purchaseTerms];
251
+ //
252
+ // // Strip out presention_position from all listed sku items
253
+ // NSArray *cleanedOrderdMetadata = [NamiBridgeUtil stripPresentationPositionFromOrderedMetadataForPaywallMetaDict:paywallMeta];
254
+ // [paywallMeta setObject:cleanedOrderdMetadata forKey:@"formatted_skus"];
255
+ //
256
+ // [paywallMeta removeObjectForKey:@"sku_ordered_metadata"];
257
+ // [paywallMeta removeObjectForKey:@"skus"];
258
+ //
259
+ // NSDictionary *paywallStylingDict = [NamiBridgeUtil paywallStylingToPaywallStylingDict:[paywallMetadata styleData]];
260
+ // paywallMeta[@"styleData"] = paywallStylingDict;
261
+ //
262
+ // // remove keys that are inconsistent with android
263
+ // [paywallMeta removeObjectForKey:@"body"];
264
+ // [paywallMeta removeObjectForKey:@"title"];
265
+ // [paywallMeta removeObjectForKey:@"style"];
266
+ //
267
+ // [self sendEventWithName:@"AppPaywallActivate" body:@{ @"namiSkus": skuDicts,
268
+ // @"developerPaywallID": developerPaywallID,
269
+ // @"paywallMetadata": paywallMeta }];
270
+ // }
271
+ //}
282
272
 
283
273
  - (NSDictionary *)buildRestorePurchasesStateChangedDict: (enum NamiRestorePurchasesState) state
284
274
  newPurchases: (NSArray<NamiPurchase *> * _Nonnull) newPurchases
@@ -297,7 +287,7 @@ bool hasNamiEmitterListeners;
297
287
 
298
288
  NSMutableArray *newPurchaseDicts = [NSMutableArray array];
299
289
  for ( NamiPurchase *purchaseRecord in newPurchases ) {
300
- if ( purchaseRecord.skuID == nil ) {
290
+ if ( purchaseRecord.skuId == nil ) {
301
291
  }
302
292
  NSDictionary *purchaseDict = [NamiBridgeUtil purchaseToPurchaseDict:purchaseRecord];
303
293
  [newPurchaseDicts addObject:purchaseDict];
@@ -305,7 +295,7 @@ bool hasNamiEmitterListeners;
305
295
 
306
296
  NSMutableArray *oldPurchaseDicts = [NSMutableArray array];
307
297
  for ( NamiPurchase *purchaseRecord in oldPurchases ) {
308
- if ( purchaseRecord.skuID == nil ) {
298
+ if ( purchaseRecord.skuId == nil ) {
309
299
  }
310
300
  NSDictionary *purchaseDict = [NamiBridgeUtil purchaseToPurchaseDict:purchaseRecord];
311
301
  [oldPurchaseDicts addObject:purchaseDict];
@@ -3,123 +3,23 @@
3
3
  // RNNami
4
4
  //
5
5
  // Created by Kendall Gelner on 4/8/20.
6
- // Copyright © 2020 Facebook. All rights reserved.
6
+ // Copyright © 2020-2023 Nami ML Inc. All rights reserved.
7
7
  //
8
8
 
9
- #import <Foundation/Foundation.h>
10
- #import <Nami/Nami.h>
11
- #import "NamiBridgeUtil.h"
12
-
13
9
  #import <React/RCTBridgeModule.h>
14
- #import <React/RCTEventEmitter.h>
15
-
16
- #import "React/RCTViewManager.h"
17
-
18
-
19
-
20
-
21
- @interface NamiEntitlementManagerBridge : NSObject <RCTBridgeModule>
22
- @end
23
- @implementation NamiEntitlementManagerBridge (RCTExternModule)
24
-
25
-
26
- RCT_EXPORT_METHOD(isEntitlementActive:(nonnull NSString*)entitlementRefID completion:(RCTResponseSenderBlock)completion)
27
- {
28
- BOOL active = [NamiEntitlementManager isEntitlementActive:entitlementRefID];
29
- NSLog(@"Checking for %@ entitlement active, result was %@", entitlementRefID, [NSNumber numberWithBool:active] );
30
- completion(@[[NSNumber numberWithBool:active]]);
31
- }
32
-
33
-
34
- RCT_EXPORT_METHOD(getEntitlements:(RCTResponseSenderBlock)completion)
35
- {
36
- NSArray<NamiEntitlement *> *entitlements = [NamiEntitlementManager getEntitlements];
37
-
38
- NSMutableArray *entitlementDicts = [NSMutableArray new];
39
-
40
- for (NamiEntitlement *entitlement in entitlements) {
41
- NSDictionary *entitlementDict = [NamiBridgeUtil entitlementToEntitlementDict:entitlement];
42
- if ([entitlementDict count] > 0) {
43
- [entitlementDicts addObject:entitlementDict];
44
- }
45
- }
46
-
47
- completion(@[entitlementDicts]);
48
- }
49
-
50
-
51
- RCT_EXPORT_METHOD(activeEntitlements:(RCTResponseSenderBlock)completion)
52
- {
53
- NSArray<NamiEntitlement *> *entitlements = [NamiEntitlementManager activeEntitlements];
54
10
 
55
- NSMutableArray *entitlementDicts = [NSMutableArray new];
11
+ @interface RCT_EXTERN_MODULE(RNNamiEntitlementManager, NSObject)
56
12
 
57
- for (NamiEntitlement *entitlement in entitlements) {
58
- NSDictionary *entitlementDict = [NamiBridgeUtil entitlementToEntitlementDict:entitlement];
59
- if ([entitlementDict count] > 0) {
60
- [entitlementDicts addObject:entitlementDict];
61
- }
62
- }
13
+ RCT_EXTERN_METHOD(isEntitlementActive:(nullable NSString *)referenceId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
63
14
 
64
- completion(@[entitlementDicts]);
65
- }
66
-
67
- RCT_EXPORT_METHOD(setEntitlements:(NSArray *)entitlementSetterDicts)
68
- {
69
-
70
- NSMutableArray<NamiEntitlementSetter *> *entitlementSetters = [NSMutableArray array];
71
-
72
- for (NSDictionary *entitlementSetterDict in entitlementSetterDicts) {
73
- NSString *referenceID = entitlementSetterDict[@"referenceID"];
74
- NSLog(@"Entitlement to set, referenceID is %@, whole entitlement %@", referenceID, entitlementSetterDict);
75
- if (referenceID != NULL && [referenceID length] > 0) {
76
- NSString *purchasedSKUid = entitlementSetterDict[@"purchasedSKUid"];
77
- NSString *expiresStr = entitlementSetterDict[@"expires"];
78
- // TODO: figure out reverse parsing of date string passed in
79
- NSDate* expires = NULL;
80
-
81
- NSString *platormStr = entitlementSetterDict[@"platform"];
82
-
83
- NamiPlatformType platform = NamiPlatformTypeOther;
84
- if ([platormStr isEqualToString:@"android"]) {
85
- platform = NamiPlatformTypeAndroid;
86
- } else if ([platormStr isEqualToString:@"apple"]) {
87
- platform = NamiPlatformTypeApple;
88
- } else if ([platormStr isEqualToString:@"roku"]) {
89
- platform = NamiPlatformTypeRoku;
90
- } else if ([platormStr isEqualToString:@"web"]) {
91
- platform = NamiPlatformTypeWeb;
92
- }
93
-
94
- NamiEntitlementSetter *setter = [NamiEntitlementSetter alloc];
95
- setter = [setter initWithId:referenceID platform:platform purchasedSKUid:purchasedSKUid expires:expires];
96
-
97
- [entitlementSetters addObject:setter];
98
- } else {
99
- NSLog(@"Warning, entitlement to set had empty referenceID, whole entitlement is \n %@", entitlementSetterDict);
100
- }
101
- }
102
-
103
- [NamiEntitlementManager setEntitlements:entitlementSetters];
104
- }
105
-
106
- RCT_EXPORT_METHOD(clearAllEntitlements) {
107
- [NamiEntitlementManager clearAllEntitlements];
108
- }
15
+ RCT_EXTERN_METHOD(active:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
109
16
 
17
+ RCT_EXTERN_METHOD(refresh)
110
18
 
111
- @end
112
-
113
-
114
- @implementation NamiEntitlementManagerBridge
115
- RCT_EXPORT_MODULE_NO_LOAD(NamiEntitlementManagerBridge, NamiEntitlementManagerBridge)
116
-
117
- - (dispatch_queue_t)methodQueue
118
- {
119
- return dispatch_get_main_queue();
120
- }
19
+ RCT_EXTERN_METHOD(registerActiveEntitlementsHandler)
121
20
 
122
21
  + (BOOL)requiresMainQueueSetup {
123
22
  return YES;
124
23
  }
24
+
125
25
  @end
@@ -0,0 +1,74 @@
1
+ //
2
+ // NamiEntitlementManagerBridge.swift
3
+ // RNNami
4
+ //
5
+ // Copyright © 2023 Nami ML Inc.. All rights reserved.
6
+ //
7
+
8
+ import Foundation
9
+ import NamiApple
10
+ import React
11
+
12
+ @objc(RNNamiEntitlementManager)
13
+ class RNNamiEntitlementManager: RCTEventEmitter {
14
+ override func supportedEvents() -> [String]! {
15
+ return ["EntitlementsChanged"]
16
+ }
17
+
18
+ private func entitlementInToDictionary(_ entitlement: NamiEntitlement) -> NSDictionary {
19
+ let activePurchasesDict: [NSDictionary] = entitlement.activePurchases.map { purchase in
20
+ let dictionary = RNNamiPurchaseManager.purchaseToPurchaseDict(purchase)
21
+ return dictionary
22
+ }
23
+
24
+ let purchasedSkusDict: [NSDictionary] = entitlement.purchasedSkus.map { sku in
25
+ let dictionary = RNNamiPurchaseManager.skuToSKUDict(sku)
26
+ return dictionary
27
+ }
28
+ let relatedSkusDict: [NSDictionary] = entitlement.relatedSkus.map { sku in
29
+ let dictionary = RNNamiPurchaseManager.skuToSKUDict(sku)
30
+ return dictionary
31
+ }
32
+ let dictionary: [String: Any?] = [
33
+ "name": entitlement.name,
34
+ "desc": entitlement.desc,
35
+ "namiId": entitlement.namiId,
36
+ "referenceId": entitlement.referenceId,
37
+ "activePurchases": activePurchasesDict,
38
+ "relatedSkus": relatedSkusDict,
39
+ "purchasedSkus": purchasedSkusDict,
40
+ ]
41
+ return NSDictionary(dictionary: dictionary.compactMapValues { $0 })
42
+ }
43
+ @objc(isEntitlementActive:resolver:rejecter:)
44
+ func isEntitlementActive(referenceId: String, resolve: @escaping RCTPromiseResolveBlock, reject _: @escaping RCTPromiseRejectBlock) {
45
+ let isEntitlementActive = NamiEntitlementManager.isEntitlementActive(referenceId)
46
+ resolve(isEntitlementActive)
47
+ }
48
+
49
+ @objc(active:rejecter:)
50
+ func active(resolve: @escaping RCTPromiseResolveBlock, reject _: @escaping RCTPromiseRejectBlock) {
51
+ let entitlements = NamiEntitlementManager.active()
52
+ let dictionaries: [NSDictionary] = entitlements.map { entitlement in
53
+ let dictionary = self.entitlementInToDictionary(entitlement)
54
+ return dictionary
55
+ }
56
+ resolve(dictionaries)
57
+ }
58
+
59
+ @objc(refresh)
60
+ func refresh() {
61
+ NamiEntitlementManager.refresh()
62
+ }
63
+
64
+ @objc(registerActiveEntitlementsHandler)
65
+ func registerActiveEntitlementsHandler() {
66
+ NamiEntitlementManager.registerActiveEntitlementsHandler { activeEntitlements in
67
+ let dictionaries: [NSDictionary] = activeEntitlements.map { entitlement in
68
+ let dictionary = self.entitlementInToDictionary(entitlement)
69
+ return dictionary
70
+ }
71
+ self.sendEvent(withName: "EntitlementsChanged", body: dictionaries)
72
+ }
73
+ }
74
+ }
@@ -3,10 +3,10 @@
3
3
  // RNNami
4
4
  //
5
5
  // Created by Kendall Gelner on 4/6/20.
6
- // Copyright © 2020 Facebook. All rights reserved.
6
+ // Copyright © 2020-2023 Nami ML Inc. All rights reserved.
7
7
  //
8
8
  #import <Foundation/Foundation.h>
9
- #import <Nami/Nami.h>
9
+ #import <NamiApple/NamiApple.h>
10
10
  #import "NamiBridgeUtil.h"
11
11
 
12
12
  #import <React/RCTBridgeModule.h>
@@ -7,7 +7,7 @@
7
7
  //
8
8
 
9
9
  #import <Foundation/Foundation.h>
10
- #import <Nami/Nami.h>
10
+ #import <NamiApple/NamiApple.h>
11
11
  #import "NamiBridgeUtil.h"
12
12
 
13
13
  #import <React/RCTBridgeModule.h>
@@ -15,6 +15,24 @@
15
15
 
16
16
  #import "React/RCTViewManager.h"
17
17
 
18
+ @interface RCT_EXTERN_MODULE(RNNamiPaywallManager, NSObject)
19
+
20
+ RCT_EXTERN_METHOD(buySkuComplete:(NSDictionary)dict)
21
+
22
+ RCT_EXTERN_METHOD(registerBuySkuHandler)
23
+
24
+ RCT_EXTERN_METHOD(registerCloseHandler:(BOOL)blockDismiss)
25
+
26
+ RCT_EXTERN_METHOD(dismiss:(BOOL)animated completion:(RCTResponseSenderBlock)callback)
27
+
28
+ RCT_EXTERN_METHOD(displayedViewController)
29
+
30
+ + (BOOL)requiresMainQueueSetup {
31
+ return YES;
32
+ }
33
+
34
+ @end
35
+
18
36
  @interface NamiEmitter : RCTEventEmitter
19
37
  - (void)sendEventPreparePaywallForDisplayFinishedWithResult:(BOOL)success developerPaywallID: (NSString * _Nullable) developerPaywallID error:(NSError * _Nullable) error;
20
38
  + (NamiEmitter *) reactInstance;
@@ -32,22 +50,18 @@
32
50
  self = [super init];
33
51
  if (self) {
34
52
  [self setBlockPaywallRaise:false];
35
- [NamiPaywallManager registerAllowAutoRaisePaywallHandler:^BOOL{
36
- NSLog(@"Block paywall raise set to %d", [self blockPaywallRaise]);
37
- return ![self blockPaywallRaise];
38
- }];
39
53
  }
40
54
  return self;
41
55
  }
42
56
 
43
57
  RCT_EXTERN_METHOD(raisePaywall)
44
58
  - (void)raisePaywall {
45
- [NamiPaywallManager raisePaywallFromVC:nil];
59
+ [NamiCampaignManager launch];
46
60
  }
47
61
 
48
- RCT_EXPORT_METHOD(raisePaywallByDeveloperPaywallId:(NSString * _Nonnull) developerPaywallID)
62
+ RCT_EXPORT_METHOD(raisePaywallByDeveloperPaywallId)
49
63
  {
50
- [NamiPaywallManager raisePaywallWithDeveloperPaywallID:developerPaywallID fromVC:nil];
64
+ [NamiCampaignManager launch];
51
65
  }
52
66
 
53
67
  RCT_EXPORT_METHOD(blockPaywallRaise:(BOOL)blockRaise)
@@ -55,92 +69,6 @@ RCT_EXPORT_METHOD(blockPaywallRaise:(BOOL)blockRaise)
55
69
  [self setBlockPaywallRaise:blockRaise];
56
70
  }
57
71
 
58
- RCT_EXPORT_METHOD(canRaisePaywall:(RCTResponseSenderBlock)completion)
59
- {
60
- BOOL canRaise = [NamiPaywallManager canRaisePaywall];
61
- completion(@[[NSNumber numberWithBool:canRaise]]);
62
- }
63
-
64
-
65
- RCT_EXPORT_METHOD(presentNamiPaywall:(NSArray *)skuIDs metapaywallDefinition:(NSDictionary *)paywallDict)
66
- {
67
- NSString *paywallDeveloperID = paywallDict[@"developerPaywallID"];
68
- if ( paywallDeveloperID != nil ) {
69
- [NamiPaywallManager fetchCustomPaywallMetaForDeveloperID:paywallDeveloperID :^(NSArray<NamiSKU *> * _Nullable products, NSString * _Nonnull paywallDevloperID, NamiPaywall * _Nullable namiMetaPaywall) {
70
- [NamiPaywallManager presentNamiPaywallFromVC:nil products:products paywallMetadata:namiMetaPaywall backgroundImage:namiMetaPaywall.backgroundImage forNami:false];
71
- }];
72
- } else {
73
- // No way to handle this case for now as we cannot cretae a NamiMetaPaywall
74
- }
75
- }
76
-
77
- RCT_EXPORT_METHOD(fetchCustomPaywallMetaForDeveloperID:(NSString *)developerPaywallID completion:(RCTResponseSenderBlock)completion)
78
- {
79
- [NamiPaywallManager fetchCustomPaywallMetaForDeveloperID:developerPaywallID :^(NSArray<NamiSKU *> * _Nullable products, NSString * _Nonnull developerPaywallID, NamiPaywall * _Nullable paywallMetadata) {
80
- NSMutableArray<NSDictionary<NSString *,NSString *> *> *productDicts = [NSMutableArray new];
81
- for (NamiSKU *product in products) {
82
- [productDicts addObject:[NamiBridgeUtil skuToSKUDict:product]];
83
- }
84
-
85
- NSMutableDictionary *paywallMeta = [NSMutableDictionary dictionaryWithDictionary:paywallMetadata.namiPaywallInfoDict];
86
- // This part is really meant to be internally facing, scrub from dictionary
87
- // Strip out presention_position from all listed sku items
88
- NSArray *cleanedOrderdMetadata = [NamiBridgeUtil stripPresentationPositionFromOrderedMetadataForPaywallMetaDict:paywallMeta];
89
- [paywallMeta setObject:cleanedOrderdMetadata forKey:@"formatted_skus"];
90
-
91
- [paywallMeta removeObjectForKey:@"sku_ordered_metadata"];
92
- [paywallMeta removeObjectForKey:@"skus"];
93
-
94
- NSDictionary *paywallStylingDict = [NamiBridgeUtil paywallStylingToPaywallStylingDict:[paywallMetadata styleData]];
95
- paywallMeta[@"styleData"] = paywallStylingDict;
96
-
97
-
98
- NSArray *wrapperArray = @[@{ @"namiSkus": productDicts,
99
- @"developerPaywallID": developerPaywallID,
100
- @"paywallMetadata": paywallMeta }];
101
- completion(wrapperArray);
102
- }];
103
- }
104
-
105
-
106
- RCT_EXPORT_METHOD(paywallImpression:(NSString *)developerPaywallID)
107
- {
108
- [NamiPaywallManager paywallImpressionWithDeveloperID:developerPaywallID];
109
- }
110
-
111
- RCT_EXPORT_METHOD( preparePaywallForDisplay:(BOOL)backgroundImageRequired
112
- imageFetchTimeout:(double)imageFetchTimeout )
113
- {
114
- [NamiPaywallManager preparePaywallForDisplayWithBackgroundImageRequired:backgroundImageRequired imageFetchTimeout:imageFetchTimeout prepareHandler:^(BOOL success, NSError * _Nullable error) {
115
- [[NamiEmitter reactInstance] sendEventPreparePaywallForDisplayFinishedWithResult:success developerPaywallID:nil error:error];
116
- }];
117
- }
118
-
119
- RCT_EXPORT_METHOD(preparePaywallForDisplayByDeveloperPaywallId:(NSString *)developerPaywallID
120
- backgroundImageRequired: (BOOL)backgroundImageRequired
121
- imageFetchTimeout:(double)imageFetchTimeout )
122
- {
123
- [NamiPaywallManager preparePaywallForDisplayWithDeveloperPaywallID:developerPaywallID backgroundImageRequired:backgroundImageRequired imageFetchTimeout:imageFetchTimeout prepareHandler:^(BOOL success, NSError * _Nullable error) {
124
- [[NamiEmitter reactInstance] sendEventPreparePaywallForDisplayFinishedWithResult:success developerPaywallID:developerPaywallID error:error];
125
- }];
126
- }
127
-
128
-
129
- RCT_EXPORT_METHOD(processSmartTextForProducts:(NSString *)smartText skuIDs:(NSArray<NSString *> *)skuIDs completion:(RCTResponseSenderBlock)completion)
130
- {
131
- [NamiPurchaseManager skusForSKUIDsWithSkuIDs:skuIDs productHandler:^(BOOL success, NSArray<NamiSKU *> * _Nullable skus, NSArray<NSString *> * _Nullable invalidSkuIDs, NSError * _Nullable error) {
132
- if (skus != NULL) {
133
- // Found some of the skus they were looking for, process text
134
- NSString *processedText = [NamiPaywallManager processSmartTextWithText:smartText dataStores:skus];
135
- completion(@[processedText]);
136
- } else {
137
- // No products found so cannot process smart text, just send back.
138
- completion(@[smartText]);
139
- }
140
- }];
141
- }
142
-
143
-
144
72
  @end
145
73
 
146
74
  @implementation NamiPaywallManagerBridge
@@ -0,0 +1,93 @@
1
+ //
2
+ // NamiPaywallManagerBridge.swift
3
+ // RNNami
4
+ //
5
+ // Created by macbook on 07.04.2023.
6
+ // Copyright © 2023 Nami ML INc.. All rights reserved.
7
+ //
8
+
9
+ import Foundation
10
+ import NamiApple
11
+ import React
12
+
13
+ @objc(RNNamiPaywallManager)
14
+ class RNNamiPaywallManager: RCTEventEmitter {
15
+ override func supportedEvents() -> [String]! {
16
+ return ["RegisterBuySKU", "BlockingPaywallClosed"]
17
+ }
18
+
19
+ @objc(buySkuComplete:)
20
+ func buySkuComplete(dict: NSDictionary) {
21
+ guard let jsonData = try? JSONSerialization.data(withJSONObject: dict["product"] as Any, options: []) else {
22
+ print("Error converting dictionary to JSON data")
23
+ return
24
+ }
25
+ do {
26
+ let decoder = JSONDecoder()
27
+ let product = try decoder.decode(NamiSKU.self, from: jsonData)
28
+
29
+ let dateFormatter = DateFormatter()
30
+ dateFormatter.locale = .init(identifier: "en_US_POSIX")
31
+ dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
32
+
33
+ if
34
+ let transactionID = dict["transactionID"] as? String,
35
+ let originalTransactionID = dict["originalTransactionID"] as? String,
36
+ let priceDecimal = Decimal(string: dict["price"] as! String),
37
+ let currencyCode = dict["currencyCode"] as? String,
38
+ let localeString = dict["locale"] as? String
39
+ {
40
+ let expiresDate = Date(timeIntervalSince1970: dict["purchaseDate"] as! Double? ?? 0)
41
+ let originalPurchaseDate = Date(timeIntervalSince1970: dict["originalPurchaseDate"] as! Double)
42
+ let purchaseDate = Date(timeIntervalSince1970: dict["purchaseDate"] as! Double)
43
+ let locale = Locale(identifier: localeString)
44
+ let purchaseSuccess = NamiPurchaseSuccess(
45
+ product: product,
46
+ transactionID: transactionID,
47
+ originalTransactionID: originalTransactionID,
48
+ originalPurchaseDate: originalPurchaseDate,
49
+ purchaseDate: purchaseDate,
50
+ expiresDate: expiresDate,
51
+ price: priceDecimal,
52
+ currencyCode: currencyCode,
53
+ locale: locale
54
+ )
55
+ NamiPaywallManager.buySkuComplete(purchaseSuccess: purchaseSuccess)
56
+ }
57
+ } catch {
58
+ print("Error decoding JSON: \(error)")
59
+ }
60
+ }
61
+
62
+ @objc(registerBuySkuHandler)
63
+ func registerBuySkuHandler() {
64
+ NamiPaywallManager.registerBuySkuHandler { sku in
65
+ let dictionary = RNNamiPurchaseManager.skuToSKUDict(sku)
66
+ self.sendEvent(withName: "RegisterBuySKU", body: dictionary)
67
+ }
68
+ }
69
+
70
+ @objc(registerCloseHandler:)
71
+ func registerCloseHandler(blockDismiss: Bool) {
72
+ NamiPaywallManager.registerCloseHandler { _ in
73
+ let dictionary = NSDictionary(dictionary: ["blockingPaywallClosed": true].compactMapValues { $0 })
74
+ self.sendEvent(withName: "BlockingPaywallClosed", body: dictionary)
75
+ if (blockDismiss) {
76
+ return
77
+ }
78
+ NamiPaywallManager.dismiss(animated: true, completion: {})
79
+ }
80
+ }
81
+
82
+ @objc(dismiss:callback:)
83
+ func dismiss(animated: Bool, callback: @escaping RCTResponseSenderBlock) {
84
+ NamiPaywallManager.dismiss(animated: animated) {
85
+ callback([])
86
+ }
87
+ }
88
+
89
+ @objc(displayedViewController)
90
+ func displayedViewController() {
91
+ _ = NamiPaywallManager.displayedViewController()
92
+ }
93
+ }