react-native-nami-sdk 2.0.4 → 3.0.8

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 (59) hide show
  1. package/.github/workflows/app_stg.yaml +203 -0
  2. package/.github/workflows/build.yml +2 -2
  3. package/.pre-commit-config.yaml +25 -0
  4. package/android/build.gradle +24 -13
  5. package/android/gradle/wrapper/gradle-wrapper.properties +5 -1
  6. package/android/src/main/java/com/nami/reactlibrary/Constants.kt +1 -1
  7. package/android/src/main/java/com/nami/reactlibrary/NamiBridgeModule.kt +6 -50
  8. package/android/src/main/java/com/nami/reactlibrary/NamiBridgePackage.java +1 -3
  9. package/android/src/main/java/com/nami/reactlibrary/NamiCampaignManagerBridge.kt +133 -0
  10. package/android/src/main/java/com/nami/reactlibrary/NamiCustomerManagerBridge.kt +89 -20
  11. package/android/src/main/java/com/nami/reactlibrary/NamiEmitter.kt +25 -25
  12. package/android/src/main/java/com/nami/reactlibrary/NamiEntitlementManagerBridgeModule.kt +31 -130
  13. package/android/src/main/java/com/nami/reactlibrary/NamiMLManagerBridgeModule.kt +1 -1
  14. package/android/src/main/java/com/nami/reactlibrary/NamiPaywallManagerBridgeModule.kt +36 -147
  15. package/android/src/main/java/com/nami/reactlibrary/NamiPurchaseManagerBridge.kt +37 -39
  16. package/android/src/main/java/com/nami/reactlibrary/NamiUtil.kt +50 -180
  17. package/build-utils/get_version_code.py +140 -0
  18. package/index.d.ts +20 -0
  19. package/index.js +7 -6
  20. package/ios/Nami.m +18 -72
  21. package/ios/NamiBridgeUtil.h +4 -6
  22. package/ios/NamiBridgeUtil.m +37 -99
  23. package/ios/NamiCampaignManagerBridge.m +26 -0
  24. package/ios/NamiCampaignManagerBridge.swift +107 -0
  25. package/ios/NamiCustomerManager.m +19 -24
  26. package/ios/NamiCustomerManager.swift +122 -0
  27. package/ios/NamiEmitter.m +85 -95
  28. package/ios/NamiEntitlementManagerBridge.m +7 -107
  29. package/ios/NamiEntitlementManagerBridge.swift +74 -0
  30. package/ios/NamiMLManagerBridge.m +2 -2
  31. package/ios/NamiPaywallManagerBridge.m +22 -94
  32. package/ios/NamiPaywallManagerBridge.swift +93 -0
  33. package/ios/NamiPurchaseManagerBridge.m +40 -71
  34. package/ios/NamiPurchaseManagerBridge.swift +174 -0
  35. package/ios/Podfile +2 -2
  36. package/ios/RNNami-Bridging-Header.h +5 -0
  37. package/ios/RNNami.h +0 -1
  38. package/ios/RNNami.m +1 -1
  39. package/ios/RNNami.xcodeproj/project.pbxproj +84 -8
  40. package/ios/RNNami.xcodeproj/xcshareddata/xcschemes/RNNami.xcscheme +67 -0
  41. package/package.json +1 -1
  42. package/react-native-nami-sdk.podspec +3 -3
  43. package/src/Nami.d.ts +112 -0
  44. package/src/Nami.js +10 -0
  45. package/src/NamiCampaignManager.d.ts +54 -0
  46. package/src/NamiCampaignManager.js +43 -0
  47. package/src/NamiCustomerManager.d.ts +39 -0
  48. package/src/NamiCustomerManager.js +43 -0
  49. package/src/NamiEntitlementManager.d.ts +24 -0
  50. package/src/NamiEntitlementManager.js +23 -0
  51. package/src/NamiMLManager.d.ts +5 -0
  52. package/src/NamiMLManager.js +7 -0
  53. package/src/NamiPaywallManager.d.ts +57 -0
  54. package/src/NamiPaywallManager.js +28 -0
  55. package/src/NamiPurchaseManager.d.ts +57 -0
  56. package/src/NamiPurchaseManager.js +37 -0
  57. package/src/types.ts +36 -0
  58. package/android/src/main/java/com/nami/reactlibrary/NamiAnalyticsEmitter.kt +0 -121
  59. package/ios/NamiAnalyticsEmitter.m +0 -146
package/ios/Nami.m CHANGED
@@ -2,12 +2,11 @@
2
2
  // Nami.m
3
3
  // RNNami
4
4
  //
5
- // Created by Kendall Gelner on 1/7/20.
6
- // Copyright © 2020 Nami ML Inc. All rights reserved.
5
+ // Copyright © 2020-2023 Nami ML Inc. All rights reserved.
7
6
  //
8
7
 
9
8
  #import <Foundation/Foundation.h>
10
- #import <Nami/Nami.h>
9
+ #import <NamiApple/NamiApple.h>
11
10
 
12
11
  #import <React/RCTBridgeModule.h>
13
12
  #import <React/RCTEventEmitter.h>
@@ -20,15 +19,15 @@
20
19
  @end
21
20
  @implementation NamiBridge (RCTExternModule)
22
21
 
23
- RCT_EXPORT_METHOD(configure: (NSDictionary *)configDict) {
22
+ RCT_EXPORT_METHOD(configure: (NSDictionary *)configDict completion: (RCTResponseSenderBlock) completion) {
24
23
  if ([configDict count] == 0 || [configDict[@"logLevel"] isEqual: @"DEBUG"] ) {
25
24
  NSLog(@"Configure dictionary is %@", configDict);
26
25
  }
27
26
  NSString *appID = configDict[@"appPlatformID-apple"];
28
-
27
+
29
28
  if ([appID length] > 0 ) {
30
- NamiConfiguration *config = [NamiConfiguration configurationForAppPlatformID:appID];
31
-
29
+ NamiConfiguration *config = [NamiConfiguration configurationForAppPlatformId:appID];
30
+
32
31
  NSString *logLevelString = configDict[@"logLevel"];
33
32
  if ([logLevelString isEqualToString:@"ERROR" ]) {
34
33
  config.logLevel = NamiLogLevelError;
@@ -40,18 +39,18 @@ RCT_EXPORT_METHOD(configure: (NSDictionary *)configDict) {
40
39
  // If they messed up the params, just set logging to full.
41
40
  config.logLevel = NamiLogLevelDebug;
42
41
  }
43
-
42
+
44
43
  NSString *languageString = configDict[@"namiLanguageCode"];
45
44
  if ([logLevelString length] > 0) {
46
45
  NSLog(@"Nami language code from config dictionary is %@", languageString);
47
- if ([[NamiLanguageCodes allAvailiableNamiLanguageCodes]
46
+ if ([[NamiLanguageCodes allAvailableNamiLanguageCodes]
48
47
  containsObject:[languageString lowercaseString]] ) {
49
48
  config.namiLanguageCode = languageString;
50
49
  } else {
51
- NSLog(@"Warning: Nami language code from config dictionary %@ not found in list of available Nami Language Codes:\n%@", languageString, [NamiLanguageCodes allAvailiableNamiLanguageCodes]);
50
+ NSLog(@"Warning: Nami language code from config dictionary %@ not found in list of available Nami Language Codes:\n%@", languageString, [NamiLanguageCodes allAvailableNamiLanguageCodes]);
52
51
  }
53
52
  }
54
-
53
+
55
54
  NSObject *bypassString = configDict[@"bypassStore"];
56
55
  if ( bypassString != NULL )
57
56
  {
@@ -66,25 +65,10 @@ RCT_EXPORT_METHOD(configure: (NSDictionary *)configDict) {
66
65
  }
67
66
  }
68
67
  }
69
-
70
- NSObject *developmentModeString = configDict[@"developmentMode"];
71
- if ( developmentModeString != NULL )
72
- {
73
- NSLog(@"bypassStore from dictionary is %@", configDict[@"developmentMode"]);
74
- if ([developmentModeString isKindOfClass:[NSNumber class]]) {
75
- config.developmentMode = [((NSNumber *)developmentModeString) boolValue];
76
- } else if ([developmentModeString isKindOfClass:[NSString class]] ) {
77
- if ([[((NSString *)developmentModeString) lowercaseString] hasPrefix:@"t"] )
78
- {
79
- // bypass is false by default, so we only worry about checking for enabling bypass
80
- config.developmentMode = true;
81
- }
82
- }
83
- }
84
-
68
+
85
69
  // Start commands with header iformation for Nami to let them know this is a React client.
86
- NSMutableArray *namiCommandStrings = [NSMutableArray arrayWithArray:@[@"extendedClientInfo:react-native:2.0.4"]];
87
-
70
+ NSMutableArray *namiCommandStrings = [NSMutableArray arrayWithArray:@[@"extendedClientInfo:react-native:3.0.0"]];
71
+
88
72
  // Add additional namiCommands app may have sent in.
89
73
  NSObject *appCommandStrings = configDict[@"namiCommands"];
90
74
  if ( appCommandStrings != NULL ) {
@@ -97,11 +81,13 @@ RCT_EXPORT_METHOD(configure: (NSDictionary *)configDict) {
97
81
  }
98
82
  }
99
83
  }
100
-
84
+
101
85
  config.namiCommands = namiCommandStrings;
102
86
 
103
-
104
- [Nami configureWithNamiConfig:config];
87
+
88
+ [Nami configureWith:config];
89
+ NSDictionary *dict = @{@"success": @YES};
90
+ completion(@[dict]);
105
91
  }
106
92
  }
107
93
 
@@ -109,46 +95,6 @@ RCT_EXPORT_METHOD(performNamiCommand: (NSString *)command) {
109
95
  [NamiCommand performCommand:command];
110
96
  }
111
97
 
112
- RCT_EXPORT_METHOD(setExternalIdentifier: (NSString *)externalIdentifier type:(NSString *)type completion: (RCTResponseSenderBlock) completion) {
113
-
114
- NamiExternalIdentifierType useType;
115
-
116
- if ( [type isEqualToString:@"sha256"] ) {
117
- useType = NamiExternalIdentifierTypeSha256;
118
- } else {
119
- useType = NamiExternalIdentifierTypeUuid;
120
- }
121
-
122
- NSLog(@"NamiBridge: Setting external identifier %@ of type %@", externalIdentifier, type);
123
-
124
- [Nami setExternalIdentifierWithExternalIdentifier:externalIdentifier type:useType completion:^(BOOL success, NSError * _Nullable error) {
125
- if (error) {
126
- completion(@[error]);
127
- }
128
- completion(nil);
129
- }];
130
- }
131
-
132
- RCT_EXPORT_METHOD(getExternalIdentifier:(RCTResponseSenderBlock)completion)
133
- {
134
- NSString *externalIdentifier = [Nami getExternalIdentifier];
135
-
136
- if (externalIdentifier == NULL || [externalIdentifier length] == 0) {
137
- completion(@[]);
138
- } else {
139
- completion(@[externalIdentifier]);
140
- }
141
- }
142
-
143
- RCT_EXPORT_METHOD(clearExternalIdentifier:(RCTResponseSenderBlock)completion) {
144
- NSLog(@"NamiBridge: Clearing external identifier.");
145
- [Nami clearExternalIdentifierWithCompletion:^(BOOL success, NSError * _Nullable error) {
146
- if (error) {
147
- success }
148
- completion(nil);
149
- }];
150
- }
151
-
152
98
  @end
153
99
 
154
100
  @implementation NamiBridge
@@ -2,10 +2,12 @@
2
2
  // NamiBridgeUtil.h
3
3
  // RNNami
4
4
  //
5
- // Created by Kendall Gelner on 1/9/20.
6
- // Copyright © 2020 Nami ML Inc. All rights reserved.
5
+ // Copyright © 2020-2023 Nami ML Inc. All rights reserved.
7
6
  //
8
7
 
8
+ #import <Foundation/Foundation.h>
9
+ #import <NamiApple/NamiApple.h>
10
+
9
11
  #ifndef NamiBridgeUtil_h
10
12
  #define NamiBridgeUtil_h
11
13
 
@@ -21,14 +23,10 @@
21
23
 
22
24
  + (NSDictionary<NSString *,NSString *> *) entitlementToEntitlementDict:(NamiEntitlement *)entitlement;
23
25
 
24
- + (NSDictionary<NSString *,NSString *> *) paywallStylingToPaywallStylingDict:(PaywallStyleData *)styling;
25
-
26
26
  + (NSArray *)stripPresentationPositionFromOrderedMetadataForPaywallMetaDict: (NSDictionary *)paywallMeta;
27
27
 
28
28
  + (NSDictionary<NSString *,NSString *> *) customerJourneyStateDict;
29
29
 
30
- + (NSString *)hexStringForColor:(UIColor *)color;
31
-
32
30
  @end
33
31
 
34
32
  #endif /* NamiBridgeUtil_h */
@@ -2,12 +2,11 @@
2
2
  // NamiBridgeUtil.m
3
3
  // RNNami
4
4
  //
5
- // Created by Kendall Gelner on 1/9/20.
6
- // Copyright © 2020 Nami ML Inc. All rights reserved.
5
+ // Copyright © 2020-2023 Nami ML Inc. All rights reserved.
7
6
  //
8
7
 
9
8
  #import <Foundation/Foundation.h>
10
- #import <Nami/Nami.h>
9
+ #import <NamiApple/NamiApple.h>
11
10
 
12
11
  #import "NamiBridgeUtil.h"
13
12
 
@@ -17,7 +16,7 @@
17
16
  + (NSDictionary<NSString *,NSString *> *) skuToSKUDict:(NamiSKU *)sku {
18
17
  NSMutableDictionary<NSString *,NSString *> *productDict = [NSMutableDictionary new];
19
18
 
20
- productDict[@"skuIdentifier"] = sku.platformID;
19
+ productDict[@"skuIdentifier"] = sku.platformId;
21
20
 
22
21
  SKProduct *productInt = sku.product;
23
22
  productDict[@"localizedTitle"] = productInt.localizedTitle;
@@ -28,10 +27,10 @@
28
27
  productDict[@"priceLanguage"] = productInt.priceLocale.languageCode;
29
28
  productDict[@"priceCountry"] = productInt.priceLocale.countryCode;
30
29
  productDict[@"priceCurrency"] = productInt.priceLocale.currencyCode;
31
-
30
+
32
31
  // Add smart text processed values for sku buttons to sku dictionary
33
- productDict[@"displayText"] = [sku namiDisplayText];
34
- productDict[@"displaySubText"] = [sku namiSubDisplayText];
32
+ // productDict[@"displayText"] = [sku localizedDisplayText];
33
+ // productDict[@"displaySubText"] = [sku localizedSubDisplayText];
35
34
 
36
35
  if (@available(iOS 12.0, *)) {
37
36
  if (productInt != nil && productInt.subscriptionGroupIdentifier != nil) {
@@ -71,18 +70,18 @@
71
70
 
72
71
  + (NSDictionary<NSString *,NSString *> *) purchaseToPurchaseDict:(NamiPurchase *)purchase {
73
72
  NSMutableDictionary<NSString *,id> *purchaseDict = [NSMutableDictionary new];
74
-
75
- purchaseDict[@"skuIdentifier"] = purchase.skuID;
73
+
74
+ purchaseDict[@"skuIdentifier"] = purchase.skuId;
76
75
  purchaseDict[@"transactionIdentifier"] = purchase.transactionIdentifier;
77
76
 
78
77
  // Removed, not sure why, should add back in when possible.
79
78
  // purchaseDict[@"purchaseInitiatedTimestamp"] = [self javascriptDateFromNSDate:purchase.purchaseInitiatedTimestamp];
80
-
79
+
81
80
  NSDate *subscriptionExpirationDate = purchase.expires;
82
81
  if (subscriptionExpirationDate != nil) {
83
82
  purchaseDict[@"subscriptionExpirationDate"] = [self javascriptDateFromNSDate:subscriptionExpirationDate];
84
83
  }
85
-
84
+
86
85
  NSString *convertedSourceString = @"UNKNOWN";
87
86
  switch (purchase.purchaseSource) {
88
87
  case 0:
@@ -98,9 +97,9 @@
98
97
  break;
99
98
  }
100
99
  purchaseDict[@"purchaseSource"] = convertedSourceString;
101
-
100
+
102
101
  // NamiSKU *purchaseSku = [purchase ]
103
-
102
+
104
103
  return purchaseDict;
105
104
  }
106
105
 
@@ -109,7 +108,7 @@
109
108
  + (NSArray *)stripPresentationPositionFromOrderedMetadataForPaywallMetaDict: (NSDictionary *)paywallMeta {
110
109
  NSArray *baseSkuArray = [paywallMeta objectForKey:@"sku_ordered_metadata"];
111
110
  NSMutableArray *newOrderedMetadata = [NSMutableArray new];
112
-
111
+
113
112
  if ( [baseSkuArray isKindOfClass:[NSArray class]] ) {
114
113
  for (NSDictionary *baseSkuDict in baseSkuArray) {
115
114
  NSMutableDictionary *skuFormattingDict = [NSMutableDictionary dictionaryWithDictionary:baseSkuDict];
@@ -123,16 +122,16 @@
123
122
  + (NSDictionary<NSString *,NSString *> *) entitlementToEntitlementDict:(NamiEntitlement *)entitlement {
124
123
  NSMutableDictionary<NSString *,id> *entitlementDict = [NSMutableDictionary new];
125
124
  NSLog(@"Converting entitlement %@", entitlement);
126
- entitlementDict[@"referenceID"] = [entitlement referenceID];
127
- entitlementDict[@"namiID"] = [entitlement namiID] ? [entitlement namiID] : @"";
125
+ entitlementDict[@"referenceID"] = [entitlement referenceId];
126
+ entitlementDict[@"namiID"] = [entitlement namiId] ? [entitlement namiId] : @"";
128
127
  entitlementDict[@"desc"] = [entitlement desc] ? [entitlement desc] : @"";
129
128
  entitlementDict[@"name"] = [entitlement name] ? [entitlement name] : @"";
130
-
131
- if (entitlementDict[@"referenceID"] == nil || [[entitlement referenceID] length] == 0) {
129
+
130
+ if (entitlementDict[@"referenceID"] == nil || [[entitlement referenceId] length] == 0) {
132
131
  NSLog(@"NamiBridge: Bad entitlement in system, empty referenceID.");
133
132
  return nil;
134
133
  }
135
-
134
+
136
135
  NSArray <NamiPurchase *>*activePurchases = [entitlement activePurchases];
137
136
  NSMutableArray *convertedActivePurchases = [NSMutableArray array];
138
137
  for (NamiPurchase *purchase in activePurchases) {
@@ -142,8 +141,8 @@
142
141
  }
143
142
  }
144
143
  entitlementDict[@"activePurchases"] = convertedActivePurchases;
145
-
146
- NSArray <NamiSKU *>*purchasedSKUs = [entitlement purchasedSKUs];
144
+
145
+ NSArray <NamiSKU *>*purchasedSKUs = [entitlement purchasedSkus];
147
146
  NSMutableArray *convertedPurchasedSKUs = [NSMutableArray array];
148
147
  for (NamiSKU *sku in purchasedSKUs) {
149
148
  NSDictionary *skuDict = [NamiBridgeUtil skuToSKUDict:sku];
@@ -152,9 +151,9 @@
152
151
  }
153
152
  }
154
153
  entitlementDict[@"purchasedSKUs"] = convertedPurchasedSKUs;
155
-
156
-
157
- NSArray <NamiSKU *>*relatedSKUs = [entitlement relatedSKUs];
154
+
155
+
156
+ NSArray <NamiSKU *>*relatedSKUs = [entitlement relatedSkus];
158
157
  NSMutableArray *convertedRelatedSKUs = [NSMutableArray array];
159
158
  for (NamiSKU *sku in relatedSKUs) {
160
159
  NSDictionary *skuDict = [NamiBridgeUtil skuToSKUDict:sku];
@@ -163,7 +162,7 @@
163
162
  }
164
163
  }
165
164
  entitlementDict[@"relatedSKUs"] = convertedRelatedSKUs;
166
-
165
+
167
166
  NamiPurchase *lastPurchase;
168
167
  for (NamiPurchase *purchase in [entitlement activePurchases]) {
169
168
  if (lastPurchase == NULL || ([lastPurchase purchaseInitiatedTimestamp] < [purchase purchaseInitiatedTimestamp])) {
@@ -173,26 +172,26 @@
173
172
  if (lastPurchase != NULL) {
174
173
  // entitlementDict[@"latestPurchase"] = [NamiBridgeUtil purchaseToPurchaseDict:lastPurchase];
175
174
  }
176
-
177
- NSString *lastPurchaseSKUID = [lastPurchase skuID];
178
-
175
+
176
+ NSString *lastPurchaseSKUID = [lastPurchase skuId];
177
+
179
178
  NamiSKU *lastPurchasedSKU;
180
179
  if (lastPurchaseSKUID != NULL ) {
181
- for (NamiSKU *sku in [entitlement purchasedSKUs]) {
182
- if ( [[sku platformID] isEqualToString:lastPurchaseSKUID] ) {
180
+ for (NamiSKU *sku in [entitlement purchasedSkus]) {
181
+ if ( [[sku platformId] isEqualToString:lastPurchaseSKUID] ) {
183
182
  lastPurchasedSKU = sku;
184
183
  }
185
184
  }
186
185
  }
187
-
186
+
188
187
  if (lastPurchasedSKU != NULL) {
189
- lastPurchasedSKU = [[entitlement purchasedSKUs] lastObject];
188
+ lastPurchasedSKU = [[entitlement purchasedSkus] lastObject];
190
189
  }
191
190
 
192
191
  if (lastPurchasedSKU != NULL) {
193
192
  // entitlementDict[@"lastPurchasedSKU"] = [NamiBridgeUtil skuToSKUDict:lastPurchasedSKU];
194
193
  }
195
-
194
+
196
195
  return entitlementDict;
197
196
  }
198
197
 
@@ -201,23 +200,23 @@
201
200
  + (NSString *)javascriptDateFromNSDate:(NSDate *)purchaseTimestamp {
202
201
  NSTimeZone *UTC = [NSTimeZone timeZoneWithAbbreviation: @"UTC"];
203
202
  NSISO8601DateFormatOptions options = NSISO8601DateFormatWithInternetDateTime | NSISO8601DateFormatWithDashSeparatorInDate | NSISO8601DateFormatWithColonSeparatorInTime | NSISO8601DateFormatWithTimeZone;
204
-
203
+
205
204
  return [NSISO8601DateFormatter stringFromDate:purchaseTimestamp timeZone:UTC formatOptions:options];
206
205
  }
207
206
 
208
207
 
209
208
  + (NSDictionary<NSString *,NSString *> *) customerJourneyStateDict {
210
- CustomerJourneyState *journeyState = [NamiCustomerManager currentCustomerJourneyState];
211
-
209
+ CustomerJourneyState *journeyState = [NamiCustomerManager journeyState];
210
+
212
211
  BOOL formerSubscriber = [journeyState formerSubscriber];
213
212
  BOOL inGracePeriod = [journeyState inGracePeriod];
214
213
  BOOL inTrialPeriod = [journeyState inTrialPeriod];
215
214
  BOOL inIntroOfferPeriod = [journeyState inIntroOfferPeriod];
216
-
215
+
217
216
  BOOL isCancelled = [journeyState isCancelled];
218
217
  BOOL inPause = [journeyState inPause];
219
218
  BOOL inAccountHold = [journeyState inAccountHold];
220
-
219
+
221
220
  NSDictionary *journeyDict = @{@"formerSubscriber":@(formerSubscriber),
222
221
  @"inGracePeriod":@(inGracePeriod),
223
222
  @"inTrialPeriod":@(inTrialPeriod),
@@ -229,65 +228,4 @@
229
228
  return journeyDict;
230
229
  }
231
230
 
232
- + (NSDictionary<NSString *,NSString *> *) paywallStylingToPaywallStylingDict:(PaywallStyleData *)styling {
233
- NSMutableDictionary<NSString *,id> *stylingDict = [NSMutableDictionary new];
234
- if (styling != nil) {
235
- stylingDict[@"backgroundColor"] = [NamiBridgeUtil hexStringForColor: styling.backgroundColor];
236
-
237
- stylingDict[@"bodyFontSize"] = @(styling.bodyFontSize);
238
- stylingDict[@"bodyTextColor"] = [NamiBridgeUtil hexStringForColor: styling.bodyTextColor];
239
- stylingDict[@"bodyShadowColor"] = [NamiBridgeUtil hexStringForColor: styling.bodyShadowColor];
240
- stylingDict[@"bodyShadowRadius"] = @(styling.bodyShadowRadius);
241
-
242
- stylingDict[@"titleFontSize"] = @(styling.titleFontSize);
243
- stylingDict[@"titleTextColor"] = [NamiBridgeUtil hexStringForColor: styling.titleTextColor];
244
- stylingDict[@"titleShadowColor"] = [NamiBridgeUtil hexStringForColor: styling.titleShadowColor];
245
- stylingDict[@"titleShadowRadius"] = @(styling.titleShadowRadius);
246
-
247
- stylingDict[@"closeButtonFontSize"] = @(styling.closeButtonFontSize);
248
- stylingDict[@"closeButtonTextColor"] = [NamiBridgeUtil hexStringForColor: styling.closeButtonTextColor];
249
- stylingDict[@"closeButtonShadowColor"] = [NamiBridgeUtil hexStringForColor: styling.closeButtonShadowColor];
250
- stylingDict[@"closeButtonShadowRadius"] = @(styling.closeButtonShadowRadius);
251
-
252
- stylingDict[@"bottomOverlayColor"] = [NamiBridgeUtil hexStringForColor: styling.bottomOverlayColor];
253
- stylingDict[@"bottomOverlayCornerRadius"] = @(styling.bottomOverlayCornerRadius);
254
-
255
- stylingDict[@"skuButtonColor"] = [NamiBridgeUtil hexStringForColor: styling.skuButtonColor];
256
- stylingDict[@"skuButtonTextColor"] = [NamiBridgeUtil hexStringForColor: styling.skuButtonTextColor];
257
-
258
- stylingDict[@"featuredSkusButtonColor"] = [NamiBridgeUtil hexStringForColor: styling.featuredSkusButtonColor];
259
- stylingDict[@"featuredSkusButtonTextColor"] = [NamiBridgeUtil hexStringForColor: styling.featuredSkusButtonTextColor];
260
-
261
- stylingDict[@"signinButtonFontSize"] = @(styling.signinButtonFontSize);
262
- stylingDict[@"signinButtonTextColor"] = [NamiBridgeUtil hexStringForColor: styling.signinButtonTextColor];
263
- stylingDict[@"signinButtonShadowColor"] = [NamiBridgeUtil hexStringForColor: styling.signinButtonShadowColor];
264
- stylingDict[@"signinButtonShadowRadius"] = @(styling.signinButtonShadowRadius);
265
-
266
- stylingDict[@"restoreButtonFontSize"] = @(styling.restoreButtonFontSize);
267
- stylingDict[@"restoreButtonTextColor"] = [NamiBridgeUtil hexStringForColor: styling.restoreButtonTextColor];
268
- stylingDict[@"restoreButtonShadowColor"] = [NamiBridgeUtil hexStringForColor: styling.restoreButtonShadowColor];
269
- stylingDict[@"restoreButtonShadowRadius"] = @(styling.restoreButtonShadowRadius);
270
-
271
- stylingDict[@"purchaseTermsFontSize"] = @(styling.purchaseTermsFontSize);
272
- stylingDict[@"purchaseTermsTextColor"] = [NamiBridgeUtil hexStringForColor: styling.purchaseTermsTextColor];
273
- stylingDict[@"purchaseTermsShadowColor"] = [NamiBridgeUtil hexStringForColor: styling.purchaseTermsShadowColor];
274
- stylingDict[@"purchaseTermsShadowRadius"] = @(styling.purchaseTermsShadowRadius);
275
-
276
-
277
- stylingDict[@"termsLinkColor"] = styling.termsLinkColor;
278
- }
279
-
280
- return stylingDict;
281
- }
282
-
283
- + (NSString *)hexStringForColor:(UIColor *)color {
284
- CGFloat r;
285
- CGFloat g;
286
- CGFloat b;
287
- CGFloat a;
288
- [color getRed:&r green:&g blue:&b alpha:&a];
289
- NSString *hexString=[NSString stringWithFormat:@"#%02X%02X%02X", (int)(r * 255), (int)(g * 255), (int)(b * 255)];
290
- return hexString;
291
- }
292
-
293
231
  @end
@@ -0,0 +1,26 @@
1
+ //
2
+ // NamiCampaignManager.m
3
+ // RNNami
4
+ //
5
+ // Copyright © 2023 Nami ML INc.. All rights reserved.
6
+ //
7
+
8
+ #import <React/RCTBridgeModule.h>
9
+
10
+ @interface RCT_EXTERN_MODULE(RNNamiCampaignManager, NSObject)
11
+
12
+ RCT_EXTERN_METHOD(launch:(nullable NSString *)label completion:(RCTResponseSenderBlock)callback paywallCompletion:(RCTResponseSenderBlock)cpaywallCallback)
13
+
14
+ RCT_EXTERN_METHOD(allCampaigns:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
15
+
16
+ RCT_EXTERN_METHOD(isCampaignAvailable:(nullable NSString *)label resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
17
+
18
+ RCT_EXTERN_METHOD(refresh)
19
+
20
+ RCT_EXTERN_METHOD(registerAvailableCampaignsHandler)
21
+
22
+ + (BOOL)requiresMainQueueSetup {
23
+ return YES;
24
+ }
25
+
26
+ @end
@@ -0,0 +1,107 @@
1
+ //
2
+ // NamiCampaignManagerBridge.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(RNNamiCampaignManager)
13
+ class RNNamiCampaignManager: RCTEventEmitter {
14
+ override func supportedEvents() -> [String]! {
15
+ return ["AvailableCampaignsChanged", "ResultCampaign"]
16
+ }
17
+
18
+ private func campaignInToDictionary(_ campaign: NamiCampaign) -> NSDictionary {
19
+ let dictionary: [String: Any?] = [
20
+ "id": campaign.id,
21
+ "rule": campaign.rule,
22
+ "segment": campaign.segment,
23
+ "paywall": campaign.paywall,
24
+ "type": campaign.type.rawValue,
25
+ "value": campaign.value,
26
+ ]
27
+ return NSDictionary(dictionary: dictionary.compactMapValues { $0 })
28
+ }
29
+
30
+ @objc(launch:completion:paywallCompletion:)
31
+ func launch(label: String?, callback: @escaping RCTResponseSenderBlock, paywallCallback _: @escaping RCTResponseSenderBlock) {
32
+ NamiCampaignManager.launch(label: label, launchHandler: { success, error in
33
+ callback([success, error?._code as Any])
34
+ }, paywallActionHandler: { action, sku, purchaseError, purchases in
35
+ let actionString: String
36
+ switch action {
37
+ case .show_paywall:
38
+ actionString = "SHOW_PAYWALL"
39
+ case .close_paywall:
40
+ actionString = "CLOSE_PAYWALL"
41
+ case .restore_purchases:
42
+ actionString = "RESTORE_PURCHASES"
43
+ case .sign_in:
44
+ actionString = "SIGN_IN"
45
+ case .buy_sku:
46
+ actionString = "BUY_SKU"
47
+ case .select_sku:
48
+ actionString = "SELECT_SKU"
49
+ case .purchase_selected_sku:
50
+ actionString = "PURCHASE_SELECTED_SKU"
51
+ case .purchase_success:
52
+ actionString = "PURCHASE_SUCCESS"
53
+ case .purchase_deferred:
54
+ actionString = "PURCHASE_DEFERRED"
55
+ case .purchase_failed:
56
+ actionString = "PURCHASE_FAILED"
57
+ case .purchase_cancelled:
58
+ actionString = "PURCHASE_CANCELLED"
59
+ case .purchase_unknown:
60
+ actionString = "PURCHASE_UNKNOWN"
61
+ @unknown default:
62
+ actionString = "PURCHASE_UNKNOWN"
63
+ }
64
+ let skuId = sku?.skuId
65
+ let errorSting = purchaseError?.localizedDescription
66
+ let dictionaries = purchases.map { purchase in NamiBridgeUtil.purchase(toPurchaseDict: purchase) }
67
+ let payload: [String: Any?] = [
68
+ "action": actionString,
69
+ "skuId": skuId,
70
+ "purchaseError": errorSting,
71
+ "purchases": dictionaries
72
+ ]
73
+ self.sendEvent(withName: "ResultCampaign", body: payload)
74
+ })
75
+ }
76
+
77
+ @objc(allCampaigns:rejecter:)
78
+ func allCampaigns(resolve: @escaping RCTPromiseResolveBlock, reject _: @escaping RCTPromiseRejectBlock) {
79
+ let campaigns = NamiCampaignManager.allCampaigns()
80
+ let dictionaries = campaigns.map { campaign in self.campaignInToDictionary(campaign) }
81
+ resolve(dictionaries)
82
+ }
83
+
84
+ @objc(isCampaignAvailable:resolver:rejecter:)
85
+ func isCampaignAvailable(label: String?, resolve: @escaping RCTPromiseResolveBlock, reject _: @escaping RCTPromiseRejectBlock) {
86
+ let isCampaignAvailable: Bool
87
+ if let label = label {
88
+ isCampaignAvailable = NamiCampaignManager.isCampaignAvailable(label: label)
89
+ } else {
90
+ isCampaignAvailable = NamiCampaignManager.isCampaignAvailable()
91
+ }
92
+ resolve(isCampaignAvailable)
93
+ }
94
+
95
+ @objc(refresh)
96
+ func refresh() {
97
+ NamiCampaignManager.refresh()
98
+ }
99
+
100
+ @objc(registerAvailableCampaignsHandler)
101
+ func registerForAvailableCampaigns() {
102
+ NamiCampaignManager.registerAvailableCampaignsHandler { availableCampaigns in
103
+ let dictionaries = availableCampaigns.map { campaign in self.campaignInToDictionary(campaign) }
104
+ self.sendEvent(withName: "AvailableCampaignsChanged", body: dictionaries)
105
+ }
106
+ }
107
+ }
@@ -2,42 +2,37 @@
2
2
  // NamiCustomerManager.m
3
3
  // RNNami
4
4
  //
5
- // Created by Kendall Gelner on 8/21/20.
6
- // Copyright © 2020 Nami ML Inc. All rights reserved.
5
+ // Copyright © 2020-2023 Nami ML Inc. All rights reserved.
7
6
  //
8
7
 
9
- #import <Foundation/Foundation.h>
10
- #import <Nami/Nami.h>
11
- #import "NamiBridgeUtil.h"
12
-
13
8
  #import <React/RCTBridgeModule.h>
14
- #import <React/RCTEventEmitter.h>
15
9
 
16
- #import "React/RCTViewManager.h"
10
+ @interface RCT_EXTERN_MODULE(RNNamiCustomerManager, NSObject)
17
11
 
18
- @interface NamiCustomerManagerBridge : NSObject <RCTBridgeModule>
19
- @end
20
- @implementation NamiCustomerManagerBridge (RCTExternModule)
12
+ RCT_EXTERN_METHOD(setCustomerAttribute:(NSString *)key value:(NSString *)value)
21
13
 
14
+ RCT_EXTERN_METHOD(getCustomerAttribute:(NSString *)key resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
22
15
 
23
- RCT_EXPORT_METHOD(currentCustomerJourneyState:(RCTResponseSenderBlock)completion)
24
- {
25
- NSDictionary *journeyDict = [NamiBridgeUtil customerJourneyStateDict];
26
-
27
- completion(@[journeyDict]);
28
- }
16
+ RCT_EXTERN_METHOD(clearCustomerAttribute:(NSString *)key)
29
17
 
18
+ RCT_EXTERN_METHOD(clearAllCustomerAttributes)
30
19
 
31
- @end
20
+ RCT_EXTERN_METHOD(journeyState:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
32
21
 
22
+ RCT_EXTERN_METHOD(isLoggedIn:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
33
23
 
34
- @implementation NamiCustomerManagerBridge
35
- RCT_EXPORT_MODULE_NO_LOAD(NamiCustomerManagerBridge, NamiCustomerManagerBridge)
24
+ RCT_EXTERN_METHOD(loggedInId:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
25
+
26
+ RCT_EXTERN_METHOD(deviceId:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
27
+
28
+ RCT_EXTERN_METHOD(login:(NSString *)customerId completion:(RCTResponseSenderBlock)callback)
29
+
30
+ RCT_EXTERN_METHOD(logout:(RCTResponseSenderBlock)callback)
31
+
32
+ RCT_EXTERN_METHOD(registerJourneyStateHandler)
33
+
34
+ RCT_EXTERN_METHOD(registerAccountStateHandler)
36
35
 
37
- - (dispatch_queue_t)methodQueue
38
- {
39
- return dispatch_get_main_queue();
40
- }
41
36
 
42
37
  + (BOOL)requiresMainQueueSetup {
43
38
  return YES;