react-native-acoustic-connect-beta 19.1.8 → 19.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 19.1.10 (2026-10-21)
2
+
3
+ ### Reverts
4
+
5
+ * Revert "Beta ReactNativeConnect build: 18.0.36" ([609ad7d](https://github.com/aipoweredmarketer/react-native-acoustic-connect-beta/commit/609ad7d3244ec06f27dced5864d40585c5b3c9cf))
6
+ ## 19.1.9 (2026-10-21)
7
+
8
+ ### Reverts
9
+
10
+ * Revert "Beta ReactNativeConnect build: 18.0.36" ([609ad7d](https://github.com/aipoweredmarketer/react-native-acoustic-connect-beta/commit/609ad7d3244ec06f27dced5864d40585c5b3c9cf))
1
11
  ## 19.1.8 (2026-10-07)
2
12
 
3
13
  ### Reverts
@@ -1,4 +1,4 @@
1
- #Wed Oct 07 08:57:10 GMT 2026
1
+ #Wed Oct 21 10:31:49 GMT 2026
2
2
  UseWhiteList=true
3
3
  PrintScreen=3
4
4
  UseRandomSample=false
@@ -0,0 +1,35 @@
1
+ // Copyright (C) 2026 Acoustic, L.P. All rights reserved.
2
+ //
3
+ // NOTICE: This file contains material that is confidential and proprietary to
4
+ // Acoustic, L.P. and/or other developers. No license is granted under any intellectual or
5
+ // industrial property rights of Acoustic, L.P. except as may be provided in an agreement with
6
+ // Acoustic, L.P. Any unauthorized copying or distribution of content from this file is
7
+ // prohibited.
8
+
9
+ #import <UIKit/UIKit.h>
10
+
11
+ // Implemented in Swift (AcousticConnectRNLaunch.swift).
12
+ @interface AcousticConnectRNLaunch : NSObject
13
+ + (void)applicationDidFinishLaunching;
14
+ @end
15
+
16
+ // Enables the SDK when the app finishes launching, before the JS bundle runs,
17
+ // so a notification tap that launched the app reaches the SDK. Lives in the pod
18
+ // so apps need no AppDelegate change. `queue:nil` runs the block synchronously
19
+ // on the posting (main) thread, before UIKit delivers the notification response.
20
+ @interface AcousticConnectRNLaunchObserver : NSObject
21
+ @end
22
+
23
+ @implementation AcousticConnectRNLaunchObserver
24
+
25
+ + (void)load {
26
+ [[NSNotificationCenter defaultCenter]
27
+ addObserverForName:UIApplicationDidFinishLaunchingNotification
28
+ object:nil
29
+ queue:nil
30
+ usingBlock:^(__unused NSNotification *note) {
31
+ [AcousticConnectRNLaunch applicationDidFinishLaunching];
32
+ }];
33
+ }
34
+
35
+ @end
@@ -0,0 +1,28 @@
1
+ // Copyright (C) 2026 Acoustic, L.P. All rights reserved.
2
+ //
3
+ // NOTICE: This file contains material that is confidential and proprietary to
4
+ // Acoustic, L.P. and/or other developers. No license is granted under any intellectual or
5
+ // industrial property rights of Acoustic, L.P. except as may be provided in an agreement with
6
+ // Acoustic, L.P. Any unauthorized copying or distribution of content from this file is
7
+ // prohibited.
8
+
9
+ import Foundation
10
+
11
+ /// Objective-C entry point for the launch hook in `AcousticConnectRNLaunch.m`.
12
+ ///
13
+ /// The hybrid object itself cannot be reached from Objective-C — it is a
14
+ /// Nitro Swift class, not an `NSObject` — so this thin class carries the call.
15
+ /// The stable Objective-C name lets the `.m` declare the class itself instead
16
+ /// of importing the generated Swift header, which this pod's C++ interop makes
17
+ /// unusable from Objective-C.
18
+ @objc(AcousticConnectRNLaunch)
19
+ final class AcousticConnectRNLaunch: NSObject {
20
+
21
+ /// Called synchronously on the main thread from the
22
+ /// `UIApplication.didFinishLaunchingNotification` observer.
23
+ @objc static func applicationDidFinishLaunching() {
24
+ MainActor.assumeIsolated {
25
+ HybridAcousticConnectRN.enableAtLaunchIfPushEnabled()
26
+ }
27
+ }
28
+ }
@@ -59,6 +59,20 @@ internal enum ConnectRNParsing {
59
59
  }
60
60
  }
61
61
 
62
+ /// Whether the bridge enables the SDK at app launch rather than when JS
63
+ /// first loads the module. Only with push on: the SDK's notification
64
+ /// delegate must exist before launch completes or iOS drops a cold-start
65
+ /// notification tap. `PushEnabled` alone decides it, in both push modes,
66
+ /// because `resolvePushConfig` turns push off exactly when it is false.
67
+ /// A config without AppKey or PostMessageUrl is left to the JS-time load,
68
+ /// which reports the problem once.
69
+ static func enablesAtLaunch(from connectData: [String: Any]) -> Bool {
70
+ guard let appKey = connectData["AppKey"] as? String, !appKey.isEmpty,
71
+ let postURL = connectData["PostMessageUrl"] as? String, !postURL.isEmpty
72
+ else { return false }
73
+ return parsePushEnabled(connectData["PushEnabled"])
74
+ }
75
+
62
76
  /// Resolves `PushEnabled` + `iOSPushMode` + `iOSAppGroupIdentifier` from the
63
77
  /// bundled config into a `ConnectPushConfig`. Validation errors are logged
64
78
  /// at `.error`; soft mismatches at `.warning`. The SDK always falls back to
@@ -137,26 +137,69 @@ class HybridAcousticConnectRN: HybridAcousticConnectRNSpec {
137
137
  // Constructor — auto-inits the SDK from `ConnectConfig.json`. Matches the
138
138
  // pre-existing auto-init behaviour; consumers that need consent-gated init can call
139
139
  // `disable()` immediately and `enable()` once they have permission.
140
+ //
141
+ // With push on, the SDK was already enabled at app launch (see
142
+ // `enableAtLaunchIfPushEnabled()`), so this is then a no-op.
140
143
  override init() {
141
144
  self.consumerSuppliedAutoLayout =
142
145
  ConnectRNParsing.suppliesAutoLayout(Self.parseConnectConfigJSON() ?? [:])
143
146
 
144
147
  super.init()
145
148
 
146
- Task { @MainActor [weak self] in
147
- self?.load()
149
+ Task { @MainActor in
150
+ HybridAcousticConnectRN.loadIfNeeded()
148
151
  }
149
152
 
150
153
  bridgeLog.info("HybridAcousticConnectRN constructed; load() dispatched on main actor.")
151
154
  }
152
155
 
156
+ /// Set once `load()` has enabled the SDK in this process. Together with
157
+ /// `ConnectSDK.shared.isEnabled` it tells `loadIfNeeded()` that the work
158
+ /// is already done: a JS reload constructs a new hybrid, and `enable()`
159
+ /// from JS re-runs the load, neither of which should re-apply the config
160
+ /// on top of a running SDK. After `disable()` the SDK reports not
161
+ /// enabled, so a later load still re-initialises it.
162
+ @MainActor private static var loadedInProcess = false
163
+
164
+ /// Enables the SDK at app launch when push is on.
165
+ ///
166
+ /// The iOS SDK installs its `UNUserNotificationCenter` delegate inside
167
+ /// `enable()`, and iOS hands a cold-start notification tap only to a
168
+ /// delegate that exists when the app finishes launching. Enabling from
169
+ /// the hybrid's constructor waits for the JS bundle, which is too late:
170
+ /// the tap is dropped and OPEN_URL / OPEN_DIALER never run. In manual
171
+ /// mode the app forwards the tap itself, and `ConnectSDK.shared.push`
172
+ /// throws until the SDK is enabled. Both need the SDK enabled before
173
+ /// launch completes.
174
+ ///
175
+ /// Called from `AcousticConnectRNLaunch` on
176
+ /// `UIApplication.didFinishLaunchingNotification`, which UIKit posts
177
+ /// before it delivers the notification response. Push off keeps the
178
+ /// existing timing: the SDK is enabled when JS first loads the module.
179
+ @MainActor
180
+ static func enableAtLaunchIfPushEnabled() {
181
+ guard let connectData = parseConnectConfigJSON(),
182
+ ConnectRNParsing.enablesAtLaunch(from: connectData) else { return }
183
+ bridgeLog.info("Push is on: enabling the SDK at app launch so a cold-start notification tap reaches it.")
184
+ load()
185
+ }
186
+
187
+ @MainActor
188
+ static func loadIfNeeded() {
189
+ if loadedInProcess && ConnectSDK.shared.isEnabled {
190
+ bridgeLog.info("SDK already enabled in this process; load() skipped.")
191
+ return
192
+ }
193
+ load()
194
+ }
195
+
153
196
  // `load()` calls into the MainActor-isolated `ConnectSDK.shared` API.
154
197
  // Marking the method `@MainActor` means Swift can verify the SDK calls
155
198
  // without an inner dispatch, and it makes the contract explicit for any
156
199
  // future caller.
157
200
  @MainActor
158
- func load() {
159
- let connectData = Self.parseConnectConfigJSON()
201
+ static func load() {
202
+ let connectData = parseConnectConfigJSON()
160
203
 
161
204
  guard let connectData = connectData else {
162
205
  configLog.error("AcousticConnectRNConfig.bundle missing or unreadable. SDK not initialised. Verify ConnectConfig.json at your project root and re-run `pod install`.")
@@ -213,7 +256,8 @@ class HybridAcousticConnectRN: HybridAcousticConnectRNSpec {
213
256
  // Apply remaining programmatic overrides (everything other than the
214
257
  // two enable parameters) AFTER enable — matches the order in the SDK's
215
258
  // own ConnectSDK.shared.enable(with:) implementation.
216
- self.applyConnectConfig(connectData)
259
+ applyConnectConfig(connectData)
260
+ loadedInProcess = true
217
261
 
218
262
  bridgeLog.info("SDK initialised: appKey length=\(appKey.count), push=\(pushConfig.modeDescription, privacy: .public), isReactNative=true, wrapNavigationContainer=true")
219
263
  }
@@ -241,7 +285,7 @@ class HybridAcousticConnectRN: HybridAcousticConnectRNSpec {
241
285
  /// a fully-initialised SDK. AppKey and PostMessageUrl are skipped here —
242
286
  /// they're passed to enable directly because the SDK's bundle-read
243
287
  /// short-circuits `tempConfigDict` for those two specifically.
244
- private func applyConnectConfig(_ connectData: [String: Any]) {
288
+ private static func applyConnectConfig(_ connectData: [String: Any]) {
245
289
  let eocoreKeys = [
246
290
  "CachingLevel", "DoPostAppComesFromBackground", "DoPostAppGoesToBackground", "DoPostAppGoesToClose",
247
291
  "DoPostAppIsLaunched", "DoPostOnIntervals", "DynamicConfigurationEnabled", "HasToPersistLocalCache",
@@ -326,7 +370,7 @@ class HybridAcousticConnectRN: HybridAcousticConnectRNSpec {
326
370
  /// which the native SDK no-ops if it's already enabled.
327
371
  func enable() throws -> Bool {
328
372
  bridgeLog.info("enable() called from JS.")
329
- Task { @MainActor [weak self] in self?.load() }
373
+ Task { @MainActor in HybridAcousticConnectRN.loadIfNeeded() }
330
374
  return true
331
375
  }
332
376
 
package/package.json CHANGED
@@ -228,7 +228,7 @@
228
228
  "source": "src/index",
229
229
  "summary": "react-native ios android tealeaf connect cxa wxca er enhanced-replay",
230
230
  "types": "./lib/typescript/src/index.d.ts",
231
- "version": "19.1.8",
231
+ "version": "19.1.10",
232
232
  "workspaces": [
233
233
  "example",
234
234
  "Examples/bare-workflow"