react-native-nami-sdk 3.3.0-beta.8 → 3.3.1

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 (106) hide show
  1. package/.prettierrc +4 -0
  2. package/README.md +9 -9
  3. package/android/README.md +3 -2
  4. package/android/build.gradle +27 -19
  5. package/android/gradle/wrapper/gradle-wrapper.properties +1 -1
  6. package/android/gradlew +0 -0
  7. package/android/src/main/AndroidManifest.xml +1 -1
  8. package/android/src/main/java/com/namiml/reactnative/Constants.kt +3 -0
  9. package/android/src/main/java/com/namiml/reactnative/NamiBridgeModule.kt +97 -0
  10. package/android/src/main/java/com/namiml/reactnative/NamiBridgePackage.java +140 -0
  11. package/android/src/main/java/com/{nami/reactlibrary → namiml/reactnative}/NamiCampaignManagerBridge.kt +25 -32
  12. package/android/src/main/java/com/{nami/reactlibrary → namiml/reactnative}/NamiCustomerManagerBridge.kt +14 -6
  13. package/android/src/main/java/com/{nami/reactlibrary/NamiEntitlementManagerBridgeModule.kt → namiml/reactnative/NamiEntitlementManagerBridge.kt} +18 -8
  14. package/android/src/main/java/com/namiml/reactnative/NamiFlowManagerBridge.kt +79 -0
  15. package/android/src/main/java/com/namiml/reactnative/NamiPaywallManagerBridgeModule.kt +197 -0
  16. package/android/src/main/java/com/namiml/reactnative/NamiPurchaseManagerBridge.kt +107 -0
  17. package/android/src/main/java/com/{nami/reactlibrary → namiml/reactnative}/NamiUtil.kt +61 -23
  18. package/{index.d.ts → dist/index.d.ts} +0 -2
  19. package/dist/specs/NativeNami.d.ts +16 -0
  20. package/dist/specs/NativeNamiCampaignManager.d.ts +82 -0
  21. package/dist/specs/NativeNamiCustomerManager.d.ts +29 -0
  22. package/dist/specs/NativeNamiEntitlementManager.d.ts +45 -0
  23. package/dist/specs/NativeNamiFlowManager.d.ts +10 -0
  24. package/dist/specs/NativeNamiPaywallManager.d.ts +72 -0
  25. package/dist/specs/NativeNamiPurchaseManager.d.ts +27 -0
  26. package/dist/src/Nami.d.ts +6 -0
  27. package/dist/src/NamiCampaignManager.d.ts +29 -0
  28. package/{src → dist/src}/NamiCustomerManager.d.ts +11 -13
  29. package/dist/src/NamiEntitlementManager.d.ts +13 -0
  30. package/dist/src/NamiFlowManager.d.ts +13 -0
  31. package/dist/src/NamiPaywallManager.d.ts +30 -0
  32. package/dist/src/NamiPurchaseManager.d.ts +16 -0
  33. package/dist/src/transformers.d.ts +3 -0
  34. package/{src → dist/src}/types.d.ts +36 -6
  35. package/dist/src/version.d.ts +5 -0
  36. package/index.ts +0 -2
  37. package/ios/Nami.m +9 -87
  38. package/ios/Nami.swift +89 -0
  39. package/ios/NamiCampaignManagerBridge.m +3 -3
  40. package/ios/NamiCampaignManagerBridge.swift +47 -61
  41. package/ios/NamiCustomerManager.m +2 -2
  42. package/ios/NamiCustomerManager.swift +11 -3
  43. package/ios/NamiEntitlementManagerBridge.m +2 -3
  44. package/ios/NamiEntitlementManagerBridge.swift +47 -39
  45. package/ios/NamiFlowManagerBridge.m +4 -2
  46. package/ios/NamiFlowManagerBridge.swift +27 -6
  47. package/ios/NamiPaywallManagerBridge.m +3 -3
  48. package/ios/NamiPaywallManagerBridge.swift +24 -6
  49. package/ios/NamiPurchaseManagerBridge.m +3 -4
  50. package/ios/NamiPurchaseManagerBridge.swift +14 -15
  51. package/ios/RNNami-Bridging-Header.h +1 -3
  52. package/package.json +20 -8
  53. package/react-native-config.js +9 -0
  54. package/react-native-nami-sdk.podspec +17 -3
  55. package/scripts/generate-version.ts +18 -0
  56. package/specs/NativeNami.ts +17 -0
  57. package/specs/NativeNamiCampaignManager.ts +94 -0
  58. package/specs/NativeNamiCustomerManager.ts +37 -0
  59. package/specs/NativeNamiEntitlementManager.ts +54 -0
  60. package/specs/NativeNamiFlowManager.ts +13 -0
  61. package/specs/NativeNamiPaywallManager.ts +86 -0
  62. package/specs/NativeNamiPurchaseManager.ts +32 -0
  63. package/src/Nami.ts +31 -18
  64. package/src/NamiCampaignManager.ts +57 -53
  65. package/src/NamiCustomerManager.ts +55 -81
  66. package/src/NamiEntitlementManager.ts +49 -36
  67. package/src/NamiFlowManager.ts +42 -44
  68. package/src/NamiPaywallManager.ts +84 -139
  69. package/src/NamiPurchaseManager.ts +66 -70
  70. package/src/transformers.ts +21 -0
  71. package/src/types.ts +40 -7
  72. package/src/version.ts +5 -0
  73. package/tsconfig.json +24 -22
  74. package/.eslintignore +0 -3
  75. package/.eslintrc.js +0 -52
  76. package/.github/workflows/CI.yaml +0 -341
  77. package/.github/workflows/app_prod.yaml +0 -387
  78. package/.github/workflows/app_stg.yaml +0 -398
  79. package/.github/workflows/build.yml +0 -70
  80. package/.pre-commit-config.yaml +0 -24
  81. package/.prettierrc.js +0 -7
  82. package/android/src/main/java/com/nami/reactlibrary/Constants.kt +0 -3
  83. package/android/src/main/java/com/nami/reactlibrary/NamiBridgeModule.kt +0 -141
  84. package/android/src/main/java/com/nami/reactlibrary/NamiBridgePackage.java +0 -51
  85. package/android/src/main/java/com/nami/reactlibrary/NamiFlowManagerBridge.kt +0 -60
  86. package/android/src/main/java/com/nami/reactlibrary/NamiMLManagerBridgeModule.kt +0 -58
  87. package/android/src/main/java/com/nami/reactlibrary/NamiManagerBridge.kt +0 -26
  88. package/android/src/main/java/com/nami/reactlibrary/NamiPaywallManagerBridgeModule.kt +0 -258
  89. package/android/src/main/java/com/nami/reactlibrary/NamiPurchaseManagerBridge.kt +0 -108
  90. package/build-utils/get_version_code.py +0 -140
  91. package/build-utils/preflight.py +0 -46
  92. package/ios/NamiMLManagerBridge.m +0 -93
  93. package/ios/NamiManager.m +0 -18
  94. package/ios/NamiManager.swift +0 -30
  95. package/ios/RNNami.h +0 -10
  96. package/ios/RNNami.m +0 -13
  97. package/src/Nami.d.ts +0 -8
  98. package/src/NamiCampaignManager.d.ts +0 -18
  99. package/src/NamiEntitlementManager.d.ts +0 -15
  100. package/src/NamiFlowManager.d.ts +0 -32
  101. package/src/NamiMLManager.d.ts +0 -7
  102. package/src/NamiMLManager.ts +0 -13
  103. package/src/NamiManager.d.ts +0 -5
  104. package/src/NamiManager.ts +0 -14
  105. package/src/NamiPaywallManager.d.ts +0 -34
  106. package/src/NamiPurchaseManager.d.ts +0 -20
@@ -2,7 +2,7 @@
2
2
  // NamiCampaignManagerBridge.swift
3
3
  // RNNami
4
4
  //
5
- // Copyright © 2023 Nami ML Inc. All rights reserved.
5
+ // Copyright © 2020-2025 Nami ML Inc. All rights reserved.
6
6
  //
7
7
 
8
8
  import Foundation
@@ -10,6 +10,10 @@ import NamiApple
10
10
  import os
11
11
  import React
12
12
 
13
+ // #if RCT_NEW_ARCH_ENABLED
14
+ // extension RNNamiCampaignManager: RCTTurboModule {}
15
+ // #endif
16
+
13
17
  @objc(RNNamiCampaignManager)
14
18
  class RNNamiCampaignManager: RCTEventEmitter {
15
19
  public static var shared: RNNamiCampaignManager?
@@ -20,7 +24,7 @@ class RNNamiCampaignManager: RCTEventEmitter {
20
24
  }
21
25
 
22
26
  override func supportedEvents() -> [String]! {
23
- return ["AvailableCampaignsChanged", "ResultCampaign"]
27
+ return ["AvailableCampaignsChanged", "NamiPaywallEvent"]
24
28
  }
25
29
 
26
30
  private func campaignInToDictionary(_ campaign: NamiCampaign) -> NSDictionary {
@@ -42,66 +46,44 @@ class RNNamiCampaignManager: RCTEventEmitter {
42
46
  return false
43
47
  }
44
48
 
49
+ private func mapPaywallActionToJS(_ action: NamiPaywallAction) -> String {
50
+ switch action {
51
+ case .show_paywall: return "SHOW_PAYWALL"
52
+ case .close_paywall: return "CLOSE_PAYWALL"
53
+ case .restore_purchases: return "RESTORE_PURCHASES"
54
+ case .sign_in: return "SIGN_IN"
55
+ case .buy_sku: return "BUY_SKU"
56
+ case .select_sku: return "SELECT_SKU"
57
+ case .purchase_selected_sku: return "PURCHASE_SELECTED_SKU"
58
+ case .purchase_success: return "PURCHASE_SUCCESS"
59
+ case .purchase_pending: return "PURCHASE_PENDING"
60
+ case .purchase_deferred: return "PURCHASE_DEFERRED"
61
+ case .purchase_failed: return "PURCHASE_FAILED"
62
+ case .purchase_cancelled: return "PURCHASE_CANCELLED"
63
+ case .purchase_unknown: return "PURCHASE_UNKNOWN"
64
+ case .deeplink: return "DEEPLINK"
65
+ case .toggle_change: return "TOGGLE_CHANGE"
66
+ case .page_change: return "PAGE_CHANGE"
67
+ case .slide_change: return "SLIDE_CHANGE"
68
+ case .nami_collapsible_drawer_open: return "COLLAPSIBLE_DRAWER_OPEN"
69
+ case .nami_collapsible_drawer_close: return "COLLAPSIBLE_DRAWER_CLOSE"
70
+ case .video_play: return "VIDEO_STARTED"
71
+ case .video_pause: return "VIDEO_PAUSED"
72
+ case .video_resume: return "VIDEO_RESUMED"
73
+ case .video_end: return "VIDEO_ENDED"
74
+ case .video_change: return "VIDEO_CHANGED"
75
+ case .video_mute: return "VIDEO_MUTED"
76
+ case .video_unmute: return "VIDEO_UNMUTED"
77
+ @unknown default:
78
+ return "UNKNOWN"
79
+ }
80
+ }
81
+
45
82
  func handlePaywallAction(
46
83
  paywallEvent: NamiPaywallEvent
47
84
  ) {
48
- var actionString: String
49
- switch paywallEvent.action {
50
- case .show_paywall:
51
- actionString = "SHOW_PAYWALL"
52
- case .close_paywall:
53
- actionString = "CLOSE_PAYWALL"
54
- case .restore_purchases:
55
- actionString = "RESTORE_PURCHASES"
56
- case .sign_in:
57
- actionString = "SIGN_IN"
58
- case .buy_sku:
59
- actionString = "BUY_SKU"
60
- case .select_sku:
61
- actionString = "SELECT_SKU"
62
- case .purchase_selected_sku:
63
- actionString = "PURCHASE_SELECTED_SKU"
64
- case .purchase_success:
65
- actionString = "PURCHASE_SUCCESS"
66
- case .purchase_pending:
67
- actionString = "PURCHASE_PENDING"
68
- case .purchase_deferred:
69
- actionString = "PURCHASE_DEFERRED"
70
- case .purchase_failed:
71
- actionString = "PURCHASE_FAILED"
72
- case .purchase_cancelled:
73
- actionString = "PURCHASE_CANCELLED"
74
- case .purchase_unknown:
75
- actionString = "PURCHASE_UNKNOWN"
76
- case .deeplink:
77
- actionString = "DEEPLINK"
78
- case .toggle_change:
79
- actionString = "TOGGLE_CHANGE"
80
- case .page_change:
81
- actionString = "PAGE_CHANGE"
82
- case .slide_change:
83
- actionString = "SLIDE_CHANGE"
84
- case .nami_collapsible_drawer_open:
85
- actionString = "COLLAPSIBLE_DRAWER_OPEN"
86
- case .nami_collapsible_drawer_close:
87
- actionString = "COLLAPSIBLE_DRAWER_CLOSE"
88
- case .video_play:
89
- actionString = "VIDEO_STARTED"
90
- case .video_pause:
91
- actionString = "VIDEO_PAUSED"
92
- case .video_resume:
93
- actionString = "VIDEO_RESUMED"
94
- case .video_end:
95
- actionString = "VIDEO_ENDED"
96
- case .video_change:
97
- actionString = "VIDEO_CHANGED"
98
- case .video_mute:
99
- actionString = "VIDEO_MUTED"
100
- case .video_unmute:
101
- actionString = "VIDEO_UNMUTED"
102
- default:
103
- actionString = "UNKNOWN"
104
- }
85
+ let actionString = mapPaywallActionToJS(paywallEvent.action)
86
+
105
87
  let errorSting = paywallEvent.purchaseError?.localizedDescription
106
88
 
107
89
  let dictionaries = paywallEvent.purchases.map { purchase in RNNamiPurchaseManager.purchaseToPurchaseDict(purchase) }
@@ -155,7 +137,9 @@ class RNNamiCampaignManager: RCTEventEmitter {
155
137
  "timeSpentOnPaywall": paywallEvent.timeSpentOnPaywall,
156
138
  ]
157
139
 
158
- RNNamiCampaignManager.shared?.sendEvent(withName: "ResultCampaign", body: payload)
140
+ DispatchQueue.main.async {
141
+ RNNamiCampaignManager.shared?.sendEvent(withName: "NamiPaywallEvent", body: payload)
142
+ }
159
143
  }
160
144
 
161
145
  func handleLaunch(callback: @escaping RCTResponseSenderBlock, success: Bool, error: Error?) {
@@ -283,7 +267,9 @@ class RNNamiCampaignManager: RCTEventEmitter {
283
267
  func registerForAvailableCampaigns() {
284
268
  NamiCampaignManager.registerAvailableCampaignsHandler { availableCampaigns in
285
269
  let dictionaries = availableCampaigns.map { campaign in self.campaignInToDictionary(campaign) }
286
- RNNamiCampaignManager.shared?.sendEvent(withName: "AvailableCampaignsChanged", body: dictionaries)
270
+ DispatchQueue.main.async {
271
+ RNNamiCampaignManager.shared?.sendEvent(withName: "AvailableCampaignsChanged", body: dictionaries)
272
+ }
287
273
  }
288
274
  }
289
275
  }
@@ -2,7 +2,7 @@
2
2
  // NamiCustomerManager.m
3
3
  // RNNami
4
4
  //
5
- // Copyright © 2020-2023 Nami ML Inc. All rights reserved.
5
+ // Copyright © 2020-2025 Nami ML Inc. All rights reserved.
6
6
  //
7
7
 
8
8
  #import <React/RCTBridgeModule.h>
@@ -43,7 +43,7 @@ RCT_EXTERN_METHOD(registerAccountStateHandler)
43
43
 
44
44
 
45
45
  + (BOOL)requiresMainQueueSetup {
46
- return YES;
46
+ return NO;
47
47
  }
48
48
 
49
49
  @end
@@ -2,13 +2,17 @@
2
2
  // NamiCustomerManager.swift
3
3
  // RNNami
4
4
  //
5
- // Copyright © 2023 Nami ML INc.. All rights reserved.
5
+ // Copyright © 2020-2025 Nami ML Inc. All rights reserved.
6
6
  //
7
7
 
8
8
  import Foundation
9
9
  import NamiApple
10
10
  import React
11
11
 
12
+ // #if RCT_NEW_ARCH_ENABLED
13
+ // extension RNNamiCustomerManager: RCTTurboModule {}
14
+ // #endif
15
+
12
16
  @objc(RNNamiCustomerManager)
13
17
  class RNNamiCustomerManager: RCTEventEmitter {
14
18
  public static var shared: RNNamiCustomerManager?
@@ -119,7 +123,9 @@ class RNNamiCustomerManager: RCTEventEmitter {
119
123
  func registerJourneyStateHandler() {
120
124
  NamiCustomerManager.registerJourneyStateHandler { journeyState in
121
125
  let dictionary = self.journeyStateToDictionary(journeyState)
122
- RNNamiCustomerManager.shared?.sendEvent(withName: "JourneyStateChanged", body: dictionary)
126
+ DispatchQueue.main.async {
127
+ RNNamiCustomerManager.shared?.sendEvent(withName: "JourneyStateChanged", body: dictionary)
128
+ }
123
129
  }
124
130
  }
125
131
 
@@ -160,7 +166,9 @@ class RNNamiCustomerManager: RCTEventEmitter {
160
166
  "success": success,
161
167
  "error": error?._code as Any,
162
168
  ]
163
- RNNamiCustomerManager.shared?.sendEvent(withName: "AccountStateChanged", body: payload)
169
+ DispatchQueue.main.async {
170
+ RNNamiCustomerManager.shared?.sendEvent(withName: "AccountStateChanged", body: payload)
171
+ }
164
172
  }
165
173
  }
166
174
  }
@@ -2,8 +2,7 @@
2
2
  // NamiEntitlementManagerBridge.m
3
3
  // RNNami
4
4
  //
5
- // Created by Kendall Gelner on 4/8/20.
6
- // Copyright © 2020-2023 Nami ML Inc. All rights reserved.
5
+ // Copyright © 2020-2025 Nami ML Inc. All rights reserved.
7
6
  //
8
7
 
9
8
  #import <React/RCTBridgeModule.h>
@@ -21,7 +20,7 @@ RCT_EXTERN_METHOD(registerActiveEntitlementsHandler)
21
20
  RCT_EXTERN_METHOD(clearProvisionalEntitlementGrants)
22
21
 
23
22
  + (BOOL)requiresMainQueueSetup {
24
- return YES;
23
+ return NO;
25
24
  }
26
25
 
27
26
  @end
@@ -2,13 +2,17 @@
2
2
  // NamiEntitlementManagerBridge.swift
3
3
  // RNNami
4
4
  //
5
- // Copyright © 2023 Nami ML Inc.. All rights reserved.
5
+ // Copyright © 2023-2025 Nami ML Inc. All rights reserved.
6
6
  //
7
7
 
8
8
  import Foundation
9
9
  import NamiApple
10
10
  import React
11
11
 
12
+ // #if RCT_NEW_ARCH_ENABLED
13
+ // extension RNNamiEntitlementManager: RCTTurboModule {}
14
+ // #endif
15
+
12
16
  @objc(RNNamiEntitlementManager)
13
17
  class RNNamiEntitlementManager: RCTEventEmitter {
14
18
  public static var shared: RNNamiEntitlementManager?
@@ -18,70 +22,74 @@ class RNNamiEntitlementManager: RCTEventEmitter {
18
22
  RNNamiEntitlementManager.shared = self
19
23
  }
20
24
 
25
+ override static func requiresMainQueueSetup() -> Bool {
26
+ return false
27
+ }
28
+
21
29
  override func supportedEvents() -> [String]! {
22
30
  return ["EntitlementsChanged"]
23
31
  }
24
32
 
25
- private func entitlementInToDictionary(_ entitlement: NamiEntitlement) -> NSDictionary {
26
- let activePurchasesDict: [NSDictionary] = entitlement.activePurchases.map { purchase in
27
- let dictionary = RNNamiPurchaseManager.purchaseToPurchaseDict(purchase)
28
- return dictionary
33
+ private func entitlementToDictionary(_ entitlement: NamiEntitlement) -> NSDictionary {
34
+ let activePurchases = entitlement.activePurchases.map {
35
+ RNNamiPurchaseManager.purchaseToPurchaseDict($0)
29
36
  }
30
37
 
31
- let purchasedSkusDict: [NSDictionary] = entitlement.purchasedSkus.map { sku in
32
- let dictionary = RNNamiPurchaseManager.skuToSKUDict(sku)
33
- return dictionary
38
+ let purchasedSkus = entitlement.purchasedSkus.map {
39
+ RNNamiPurchaseManager.skuToSKUDict($0)
34
40
  }
35
- let relatedSkusDict: [NSDictionary] = entitlement.relatedSkus.map { sku in
36
- let dictionary = RNNamiPurchaseManager.skuToSKUDict(sku)
37
- return dictionary
41
+
42
+ let relatedSkus = entitlement.relatedSkus.map {
43
+ RNNamiPurchaseManager.skuToSKUDict($0)
38
44
  }
39
45
 
40
46
  let dictionary: [String: Any?] = [
41
- "name": entitlement.name,
42
- "desc": entitlement.desc,
47
+ "name": entitlement.name ?? "",
48
+ "desc": entitlement.desc ?? "",
43
49
  "referenceId": entitlement.referenceId,
44
- "activePurchases": activePurchasesDict,
45
- "relatedSkus": relatedSkusDict,
46
- "purchasedSkus": purchasedSkusDict,
50
+ "activePurchases": activePurchases,
51
+ "relatedSkus": relatedSkus,
52
+ "purchasedSkus": purchasedSkus,
47
53
  ]
54
+
48
55
  return NSDictionary(dictionary: dictionary.compactMapValues { $0 })
49
56
  }
50
57
 
51
- @objc(isEntitlementActive:resolver:rejecter:)
52
- func isEntitlementActive(referenceId: String, resolve: @escaping RCTPromiseResolveBlock, reject _: @escaping RCTPromiseRejectBlock) {
53
- let isEntitlementActive = NamiEntitlementManager.isEntitlementActive(referenceId)
54
- resolve(isEntitlementActive)
58
+ @objc
59
+ func isEntitlementActive(_ referenceId: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter _: @escaping RCTPromiseRejectBlock) {
60
+ resolve(NamiEntitlementManager.isEntitlementActive(referenceId))
55
61
  }
56
62
 
57
- @objc(active:rejecter:)
58
- func active(resolve: @escaping RCTPromiseResolveBlock, reject _: @escaping RCTPromiseRejectBlock) {
59
- let entitlements = NamiEntitlementManager.active()
60
- let dictionaries: [NSDictionary] = entitlements.map { entitlement in
61
- let dictionary = self.entitlementInToDictionary(entitlement)
62
- return dictionary
63
+ @objc
64
+ func active(_ resolve: @escaping RCTPromiseResolveBlock,
65
+ rejecter _: @escaping RCTPromiseRejectBlock)
66
+ {
67
+ let entitlements = NamiEntitlementManager.active().map {
68
+ self.entitlementToDictionary($0)
63
69
  }
64
- resolve(dictionaries)
70
+ resolve(entitlements)
65
71
  }
66
72
 
67
- @objc(refresh)
73
+ @objc
68
74
  func refresh() {
69
- NamiEntitlementManager.refresh()
75
+ NamiEntitlementManager.refresh { entitlements in
76
+ let dicts = entitlements.map { self.entitlementToDictionary($0) }
77
+ DispatchQueue.main.async {
78
+ RNNamiEntitlementManager.shared?.sendEvent(withName: "EntitlementsChanged", body: dicts)
79
+ }
80
+ }
70
81
  }
71
82
 
72
- @objc(registerActiveEntitlementsHandler)
83
+ @objc
73
84
  func registerActiveEntitlementsHandler() {
74
- NamiEntitlementManager.registerActiveEntitlementsHandler { activeEntitlements in
75
- let dictionaries: [NSDictionary] = activeEntitlements.map { entitlement in
76
- let dictionary = self.entitlementInToDictionary(entitlement)
77
- return dictionary
85
+ NamiEntitlementManager.registerActiveEntitlementsHandler { entitlements in
86
+ let dicts = entitlements.map { self.entitlementToDictionary($0) }
87
+ DispatchQueue.main.async {
88
+ RNNamiEntitlementManager.shared?.sendEvent(withName: "EntitlementsChanged", body: dicts)
78
89
  }
79
- RNNamiEntitlementManager.shared?.sendEvent(withName: "EntitlementsChanged", body: dictionaries)
80
90
  }
81
91
  }
82
92
 
83
- @objc(clearProvisionalEntitlementGrants)
84
- func clearProvisionalEntitlementGrants() {
85
- NamiEntitlementManager.clearProvisionalEntitlementGrants()
86
- }
93
+ @objc
94
+ func clearProvisionalEntitlementGrants() {}
87
95
  }
@@ -10,11 +10,13 @@
10
10
 
11
11
  @interface RCT_EXTERN_MODULE(RNNamiFlowManager, RCTEventEmitter)
12
12
  RCT_EXTERN_METHOD(registerStepHandoff)
13
- RCT_EXTERN_METHOD(registerEventHandler:(RCTResponseSenderBlock)callback)
13
+ RCT_EXTERN_METHOD(registerEventHandler)
14
14
  RCT_EXTERN_METHOD(resume)
15
+ RCT_EXTERN_METHOD(finish)
16
+ RCT_EXTERN_METHOD(isFlowOpen:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
15
17
 
16
18
  + (BOOL)requiresMainQueueSetup {
17
- return YES;
19
+ return NO;
18
20
  }
19
21
 
20
22
  @end
@@ -9,6 +9,10 @@ import Foundation
9
9
  import NamiApple
10
10
  import React
11
11
 
12
+ // #if RCT_NEW_ARCH_ENABLED
13
+ // extension RNNamiFlowManager: RCTTurboModule {}
14
+ // #endif
15
+
12
16
  @objc(RNNamiFlowManager)
13
17
  class RNNamiFlowManager: RCTEventEmitter {
14
18
  public static var shared: RNNamiFlowManager?
@@ -19,11 +23,11 @@ class RNNamiFlowManager: RCTEventEmitter {
19
23
  }
20
24
 
21
25
  override static func requiresMainQueueSetup() -> Bool {
22
- return true
26
+ return false
23
27
  }
24
28
 
25
29
  override func supportedEvents() -> [String]! {
26
- return ["RegisterStepHandoff"]
30
+ return ["Handoff", "FlowEvent"]
27
31
  }
28
32
 
29
33
  @objc func registerStepHandoff() {
@@ -34,14 +38,18 @@ class RNNamiFlowManager: RCTEventEmitter {
34
38
  if let data = data {
35
39
  payload["handoffData"] = data
36
40
  }
37
- RNNamiFlowManager.shared?.sendEvent(withName: "RegisterStepHandoff", body: payload)
41
+
42
+ DispatchQueue.main.async {
43
+ RNNamiFlowManager.shared?.sendEvent(withName: "Handoff", body: payload)
44
+ }
38
45
  }
39
46
  }
40
47
 
41
- @objc(registerEventHandler:)
42
- func registerEventHandler(_ callback: @escaping RCTResponseSenderBlock) {
48
+ @objc func registerEventHandler() {
43
49
  NamiFlowManager.registerEventHandler { payload in
44
- callback([payload])
50
+ DispatchQueue.main.async {
51
+ RNNamiFlowManager.shared?.sendEvent(withName: "FlowEvent", body: payload)
52
+ }
45
53
  }
46
54
  }
47
55
 
@@ -50,4 +58,17 @@ class RNNamiFlowManager: RCTEventEmitter {
50
58
  NamiFlowManager.resume()
51
59
  }
52
60
  }
61
+
62
+ @objc func finish() {
63
+ DispatchQueue.main.async {
64
+ NamiFlowManager.finish()
65
+ }
66
+ }
67
+
68
+ @objc func isFlowOpen(_ resolve: @escaping RCTPromiseResolveBlock, rejecter _: @escaping RCTPromiseRejectBlock) {
69
+ DispatchQueue.main.async {
70
+ let isFlowOpen = NamiFlowManager.isFlowOpen()
71
+ resolve(isFlowOpen)
72
+ }
73
+ }
53
74
  }
@@ -1,8 +1,8 @@
1
1
  //
2
2
  // NamiPaywallManager.m
3
- // namiReactNative
3
+ // RNNami
4
4
  //
5
- // Copyright © 2023 Nami ML Inc. All rights reserved.
5
+ // Copyright © 2020-2025 Nami ML Inc. All rights reserved.
6
6
  //
7
7
 
8
8
  #import <Foundation/Foundation.h>
@@ -46,7 +46,7 @@ RCT_EXTERN_METHOD(setAppSuppliedVideoDetails:(NSString *)url name:(nullable NSSt
46
46
  RCT_EXTERN_METHOD(allowUserInteraction:(BOOL *)allowed)
47
47
 
48
48
  + (BOOL)requiresMainQueueSetup {
49
- return YES;
49
+ return NO;
50
50
  }
51
51
 
52
52
  @end
@@ -2,13 +2,17 @@
2
2
  // NamiPaywallManagerBridge.swift
3
3
  // RNNami
4
4
  //
5
- // Copyright © 2023 Nami ML Inc. All rights reserved.
5
+ // Copyright © 2020-2025 Nami ML Inc. All rights reserved.
6
6
  //
7
7
 
8
8
  import Foundation
9
9
  import NamiApple
10
10
  import React
11
11
 
12
+ // #if RCT_NEW_ARCH_ENABLED
13
+ // extension RNNamiPaywallManager: RCTTurboModule {}
14
+ // #endif
15
+
12
16
  @objc(RNNamiPaywallManager)
13
17
  class RNNamiPaywallManager: RCTEventEmitter {
14
18
  public static var shared: RNNamiPaywallManager?
@@ -44,6 +48,10 @@ class RNNamiPaywallManager: RCTEventEmitter {
44
48
  let namiSku = NamiSKU(namiId: namiId, storeId: storeId, skuType: namiSkuType)
45
49
  let priceString = dict["price"] as? String ?? "0"
46
50
 
51
+ if let store = dict["storeType"] as? String, store != "Apple" {
52
+ print("RNNamiPaywallManager - buySkuComplete called with the wrong store type \(dict)")
53
+ }
54
+
47
55
  do {
48
56
  if let transactionID = dict["transactionID"] as? String,
49
57
  let originalTransactionID = dict["originalTransactionID"] as? String,
@@ -72,7 +80,9 @@ class RNNamiPaywallManager: RCTEventEmitter {
72
80
  func registerBuySkuHandler() {
73
81
  NamiPaywallManager.registerBuySkuHandler { sku in
74
82
  let dictionary = RNNamiPurchaseManager.skuToSKUDict(sku)
75
- RNNamiPaywallManager.shared?.sendEvent(withName: "RegisterBuySKU", body: dictionary)
83
+ DispatchQueue.main.async {
84
+ RNNamiPaywallManager.shared?.sendEvent(withName: "RegisterBuySKU", body: dictionary)
85
+ }
76
86
  }
77
87
  }
78
88
 
@@ -80,7 +90,9 @@ class RNNamiPaywallManager: RCTEventEmitter {
80
90
  func registerCloseHandler() {
81
91
  NamiPaywallManager.registerCloseHandler { _ in
82
92
  let dictionary = NSDictionary(dictionary: ["PaywallCloseRequested": true].compactMapValues { $0 })
83
- RNNamiPaywallManager.shared?.sendEvent(withName: "PaywallCloseRequested", body: dictionary)
93
+ DispatchQueue.main.async {
94
+ RNNamiPaywallManager.shared?.sendEvent(withName: "PaywallCloseRequested", body: dictionary)
95
+ }
84
96
  }
85
97
  }
86
98
 
@@ -88,7 +100,9 @@ class RNNamiPaywallManager: RCTEventEmitter {
88
100
  func registerSignInHandler() {
89
101
  NamiPaywallManager.registerSignInHandler { _ in
90
102
  let dictionary = NSDictionary(dictionary: ["PaywallSignInRequested": true].compactMapValues { $0 })
91
- RNNamiPaywallManager.shared?.sendEvent(withName: "PaywallSignInRequested", body: dictionary)
103
+ DispatchQueue.main.async {
104
+ RNNamiPaywallManager.shared?.sendEvent(withName: "PaywallSignInRequested", body: dictionary)
105
+ }
92
106
  }
93
107
  }
94
108
 
@@ -96,14 +110,18 @@ class RNNamiPaywallManager: RCTEventEmitter {
96
110
  func registerRestoreHandler() {
97
111
  NamiPaywallManager.registerRestoreHandler {
98
112
  let dictionary = NSDictionary(dictionary: ["PaywallRestoreRequested": true].compactMapValues { $0 })
99
- RNNamiPaywallManager.shared?.sendEvent(withName: "PaywallRestoreRequested", body: dictionary)
113
+ DispatchQueue.main.async {
114
+ RNNamiPaywallManager.shared?.sendEvent(withName: "PaywallRestoreRequested", body: dictionary)
115
+ }
100
116
  }
101
117
  }
102
118
 
103
119
  @objc(registerDeeplinkActionHandler)
104
120
  func registerDeeplinkActionHandler() {
105
121
  NamiPaywallManager.registerDeeplinkActionHandler { url in
106
- RNNamiPaywallManager.shared?.sendEvent(withName: "PaywallDeeplinkAction", body: url)
122
+ DispatchQueue.main.async {
123
+ RNNamiPaywallManager.shared?.sendEvent(withName: "PaywallDeeplinkAction", body: url)
124
+ }
107
125
  }
108
126
  }
109
127
 
@@ -1,7 +1,8 @@
1
1
  //
2
2
  // NamiPurchaseManagerBridge.m
3
+ // RNNami
3
4
  //
4
- // Copyright © 2019 Nami ML Inc. All rights reserved.
5
+ // Copyright © 2020-2025 Nami ML Inc. All rights reserved.
5
6
  //
6
7
 
7
8
  #import <Foundation/Foundation.h>
@@ -20,8 +21,6 @@ RCT_EXTERN_METHOD(skuPurchased:(NSString *)skuId resolver:(RCTPromiseResolveBloc
20
21
 
21
22
  RCT_EXTERN_METHOD(anySkuPurchased:(NSArray*)skuIds resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
22
23
 
23
- RCT_EXTERN_METHOD(consumePurchasedSku:(NSString *)skuId)
24
-
25
24
  RCT_EXTERN_METHOD(registerPurchasesChangedHandler)
26
25
 
27
26
  RCT_EXTERN_METHOD(registerRestorePurchasesHandler)
@@ -31,7 +30,7 @@ RCT_EXTERN_METHOD(presentCodeRedemptionSheet)
31
30
  RCT_EXTERN_METHOD(restorePurchases)
32
31
 
33
32
  + (BOOL)requiresMainQueueSetup {
34
- return YES;
33
+ return NO;
35
34
  }
36
35
 
37
36
  @end
@@ -2,13 +2,17 @@
2
2
  // NamiPurchaseManagerBridge.swift
3
3
  // RNNami
4
4
  //
5
- // Copyright © 2023 Nami ML Inc. All rights reserved.
5
+ // Copyright © 2020-2025 Nami ML Inc. All rights reserved.
6
6
  //
7
7
 
8
8
  import Foundation
9
9
  import NamiApple
10
10
  import React
11
11
 
12
+ // #if RCT_NEW_ARCH_ENABLED
13
+ // extension RNNamiPurchaseManager: RCTTurboModule {}
14
+ // #endif
15
+
12
16
  @objc(RNNamiPurchaseManager)
13
17
  class RNNamiPurchaseManager: RCTEventEmitter {
14
18
  public static var shared: RNNamiPurchaseManager?
@@ -57,11 +61,12 @@ class RNNamiPurchaseManager: RCTEventEmitter {
57
61
  "id": sku.id,
58
62
  "skuId": sku.skuId,
59
63
  "type": typeString,
64
+ "name": sku.name ?? "",
60
65
  "appleProduct": productDict,
61
66
  ]
62
67
 
63
68
  if let promoId = sku.promoId {
64
- skuDict["promoId"] = sku.promoId
69
+ skuDict["promoId"] = promoId
65
70
  }
66
71
 
67
72
  return NSDictionary(dictionary: skuDict.compactMapValues { $0 })
@@ -72,19 +77,18 @@ class RNNamiPurchaseManager: RCTEventEmitter {
72
77
  if let sku = purchase.sku {
73
78
  skuDictionary = RNNamiPurchaseManager.skuToSKUDict(sku)
74
79
  }
75
- let dateFormatter = DateFormatter()
76
- dateFormatter.locale = .init(identifier: "en_US_POSIX")
77
- dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
78
- let expiresString = dateFormatter.string(from: purchase.expires ?? Date())
79
- let purchaseInitiatedString = dateFormatter.string(from: purchase.purchaseInitiatedTimestamp)
80
80
 
81
- let purchaseDict: [String: Any?] = [
81
+ var purchaseDict: [String: Any?] = [
82
82
  "skuId": purchase.skuId,
83
83
  "transactionIdentifier": purchase.transactionIdentifier,
84
84
  "sku": skuDictionary,
85
- "expires": expiresString,
86
- "purchaseInitiatedTimestamp": purchaseInitiatedString,
85
+ "purchaseInitiatedTimestamp": purchase.purchaseInitiatedTimestamp.timeIntervalSince1970 * 1000,
87
86
  ]
87
+
88
+ if let expires = purchase.expires {
89
+ purchaseDict["expires"] = expires.timeIntervalSince1970 * 1000
90
+ }
91
+
88
92
  return NSDictionary(dictionary: purchaseDict.compactMapValues { $0 })
89
93
  }
90
94
 
@@ -115,11 +119,6 @@ class RNNamiPurchaseManager: RCTEventEmitter {
115
119
  resolve(false)
116
120
  }
117
121
 
118
- @objc(consumePurchasedSku:)
119
- func consumePurchasedSku(skuId: String) {
120
- NamiPurchaseManager.consumePurchasedSku(skuId: skuId)
121
- }
122
-
123
122
  @objc(registerPurchasesChangedHandler)
124
123
  func registerPurchasesChangedHandler() {
125
124
  NamiPurchaseManager.registerPurchasesChangedHandler { purchases, purchaseState, error in
@@ -1,4 +1,2 @@
1
- //
2
- // Use this file to import your target's public headers that you would like to expose to Swift.
3
- //
4
1
  #import <React/RCTBridgeModule.h>
2
+ #import <React/RCTEventEmitter.h>