UNPKG

react-native-acoustic-connect-beta

Version:

BETA: React native plugin for Acoustic Connect

264 lines (198 loc) 10.8 kB
# react-native-acoustic-connect-beta React Native plugin for the Acoustic Connect SDK. Captures user interactions, screen replays, and analytics events on iOS and Android. Supports optional push notifications via the Connect backend. For the full product overview see the [Connect SDK overview on the developer portal](https://developer.goacoustic.com/acoustic-connect/docs/connect-sdk-overview). ## Requirements - React Native 0.82.x – 0.85.x with the new architecture - React 19.1.1 or newer (or whatever your RN version pins) - Node 20 or newer - iOS deployment target ≥ 15.1, AcousticConnect / AcousticConnectDebug pod ≥ 2.0.5 - Android `minSdk`26, `compileSdk`35, `io.github.go-acoustic:connect` in `[11.0.11, 12.0.0)` - **Expo is not supported by this package.** Expo apps should use the sibling Config Plugin (tracked separately under PES-4002 / CA-137701). ## Installation ```bash npm install react-native-acoustic-connect-beta react-native-nitro-modules cd ios && pod install ``` The plugin reads a `ConnectConfig.json` from your project root at install time (iOS via the podspec, Android via `config.gradle`) and bakes the values into the native bundles. **`ConnectConfig.json` is the single source of truth** — there is no runtime override path. A minimal config looks like: ```json { "Connect": { "AppKey": "your-app-key", "PostMessageUrl": "https://collector.example.com/collectorPost", "KillSwitchUrl": "https://collector.example.com/collector/switch/your-app-key", "useRelease": false, "PushEnabled": false, "iOSPushMode": "automatic", "iOSAppGroupIdentifier": null, "AndroidNotificationIconResName": null } } ``` Field summary (see [API reference](#api-reference) for full semantics): | Field | Default | Purpose | | --- | --- | --- | | `AppKey` | _(required)_ | Your Connect application key. | | `PostMessageUrl` | _(required)_ | Collector endpoint URL. | | `KillSwitchUrl` | _(optional)_ | Kill-switch endpoint URL. | | `useRelease` | `false` | `true` selects the release AcousticConnect iOS pod over the debug variant. | | `iOSVersion` | `""` | Pin a specific iOS pod version; empty = newest in the supported range. | | `AndroidVersion` | `""` | Pin a specific Android Connect SDK version; empty = newest in the supported range. | | `PushEnabled` | `false` | Master switch. On Android, also gates the `connect-push-fcm` artifact inclusion. | | `iOSPushMode` | `"automatic"` | iOS-only: `"automatic"` (SDK owns APNs delegate) or `"manual"` (app owns it). Ignored when `PushEnabled` is `false`. | | `iOSAppGroupIdentifier` | `null` | iOS App Group shared with the Notification Service / Notification Content extension. | | `AndroidNotificationIconResName` | `null` | Drawable resource name (no extension) for the Android notification small icon. | ## Quick start ### 1. Initialise the SDK The SDK **auto-initialises** at module load time using the values from `ConnectConfig.json`. For most apps there is no JS-side init code to write — just import the package and you're done: ```ts // index.js import AcousticConnectRN from 'react-native-acoustic-connect-beta' // SDK is already initialising on the main actor / main looper. No further // setup required. ``` For consent-gated apps (GDPR, CCPA, COPPA), use the lifecycle pair: ```ts import AcousticConnectRN from 'react-native-acoustic-connect-beta' // At app start, if you don't yet have user consent: AcousticConnectRN.disable() // Later, after the user opts in: AcousticConnectRN.enable() ``` `enable()` and `disable()` are both parameterless — all configuration comes from `ConnectConfig.json`. They're idempotent at the native layer; calling `enable()` on an already-running SDK is a no-op. ### 2. Add the `<Connect>` wrapper (declarative, in your tree) Wrap your `NavigationContainer` in `<Connect>` to enable navigation tracking, touch capture, and optional keyboard / dialog interception. The wrapper does not own SDK lifecycle — that's been done in step 1 — so it can mount, unmount, or remount freely without disrupting the session. ```tsx import { useNavigationContainerRef, NavigationContainer } from '@react-navigation/native' import { Connect } from 'react-native-acoustic-connect-beta' export default function App() { const navigationRef = useNavigationContainerRef() return ( <Connect navigationRef={navigationRef} captureKeyboardEvents captureDialogEvents > <NavigationContainer ref={navigationRef}> {/* your screens */} </NavigationContainer> </Connect> ) } ``` `<Connect>` is optional. Apps that only need custom event logging (no automatic screen / touch / keyboard tracking) can skip it entirely. ### 3. Log events (imperative, anywhere) ```ts import AcousticConnectRN from 'react-native-acoustic-connect-beta' // Custom application event AcousticConnectRN.logCustomEvent('checkout_started', { cartId: 'abc' }, 1) // Force a logical screen name (e.g. for non-NavigationContainer screens) AcousticConnectRN.setCurrentScreenName('CheckoutScreen') // Manual exception capture AcousticConnectRN.logExceptionEvent( 'Payment failed', err.stack ?? '', /* unhandled */ false ) ``` Dialog tracking helpers (`useDialogTracking`, `DialogListener`, `withAcousticAutoDialog`) instrument React Native `Alert.alert(...)` and custom dialogs automatically. See the [developer portal](https://developer.goacoustic.com/acoustic-connect/docs/react-native-integration) for details. ## API reference ### `AcousticConnectRN.enable(): boolean` Re-enables the SDK after a prior `disable()`. Reads all configuration from `ConnectConfig.json`. Returns `true` on accepted dispatch; `false` only when the platform can't satisfy a precondition (e.g. Android without an `Application` context yet). Idempotent — the native SDK short-circuits if it's already running. > The SDK also auto-initialises at module load using the same configuration, > so you typically don't need to call `enable()` at all. The method exists to > pair with `disable()` for opt-out / consent flows. ### `AcousticConnectRN.disable(): boolean` Stops data capture, flushes pending messages, releases push state. Idempotent. ### Push configuration (`ConnectConfig.json`) | Field | Type | Default | Semantics | | --- | --- | --- | --- | | `PushEnabled` | boolean | `false` | Cross-platform master switch. On Android, drives `connect-push-fcm` artifact inclusion at build time. | | `iOSPushMode` | `"automatic"` / `"manual"` | `"automatic"` | iOS-only. Ignored when `PushEnabled` is `false`. | | `iOSAppGroupIdentifier` | string \| null | `null` | iOS App Group shared with NSE / NCE for rich push payloads. | | `AndroidNotificationIconResName` | string \| null | `null` | Drawable resource name for the Android notification small icon. | #### iOS push modes - `"automatic"` — the iOS Connect SDK manages APNs token registration internally. The host app only requests user permission via `UNUserNotificationCenter`; token delivery and forwarding to the Connect backend are handled by the SDK. - `"manual"` — the host app owns APNs delegate callbacks (`application(_:didRegisterForRemoteNotificationsWithDeviceToken:)`) and forwards tokens explicitly via `ConnectSDK.shared.push.didRegisterWithToken(token)`. #### Android push The `iOSPushMode` field is iOS-only; Android push is gated solely by `PushEnabled`. On Android, FCM requires a `FirebaseMessagingService` subclass that the host app declares in its `AndroidManifest.xml`, so push is always app-driven. The host app is responsible for: - shipping `google-services.json` in `android/app/`, - implementing `FirebaseMessagingService.onNewToken(...)`, - forwarding the FCM token to the Connect SDK. The Android push-forwarding API itself is wired under follow-up work — until that lands, `PushEnabled: true` on Android only changes which artifact is on the classpath; the host-side token forwarding API is not yet exposed. ### `<Connect>` props | Prop | Type | Required | Description | | --- | --- | --- | --- | | `children` | `ReactNode` | yes | Your `NavigationContainer` (or any subtree). | | `navigationRef` | `RefObject` | recommended | Ref from `useNavigationContainerRef()`. Enables screen-name tracking. | | `captureKeyboardEvents` | `boolean` | yes | Capture iOS/Android keyboard show/hide events. | | `captureDialogEvents` | `boolean` | no (default `false`) | Auto-track `Alert.alert(...)` calls. | ### Other methods The plugin exposes the full Connect SDK surface — custom events, signals, exceptions, location, screen layout, click / text-change events, dialog events, and config-item getters/setters. Signatures are stable across platforms; see `src/specs/react-native-acoustic-connect.nitro.ts` for the typed Nitro spec and the [developer portal](https://developer.goacoustic.com/acoustic-connect/docs/react-native-integration) for end-to-end recipes. ## Migration from earlier versions See [Migration-Guide.md](./Migration-Guide.md) for the steps to move from the legacy `NativeModules.AcousticConnectRN` interface to the current ESM exports and the `<Connect>` component. ## Troubleshooting ### `npm install` peer-dependency conflicts If `npm install` errors out on a peer-dependency resolution involving Expo or older `react-native-nitro-modules` versions, retry with: ```bash npm install react-native-nitro-modules --legacy-peer-deps ``` This usually only happens when an existing project pulls in stale Expo transitives. Permanent fix: align RN, React, and Nitro versions with the [Requirements](#requirements) section above. ### iOS — `pod install` fails with `[Connect] requires AcousticConnect >= 2.0.5` You've pinned an older `iOSVersion` in `ConnectConfig.json`. Bump it to a 2.0.5+ release (or leave it empty for the newest available) and re-run `pod install`. ### Android — Gradle resolution fails on `io.github.go-acoustic:connect` The strict constraint at `[11.0.11, 12.0.0)` is rejecting your pin. Bump `AndroidVersion` in `ConnectConfig.json` to a release within that range (or leave it empty for the newest 11.x available). 12.x is intentionally outside the supported range pending compatibility validation — track that work separately if you need it. ### Gradle can't find `node` Common when Gradle is launched outside an NVM-loaded shell. Either: - Stop the daemon (`./gradlew --stop`) and re-run `npm run android` from a shell where `which node` resolves, or - Symlink node onto a stable PATH: `ln -sf "$(which node)" /opt/homebrew/bin/node`. --- For more, see the [Connect React Native integration guide](https://developer.goacoustic.com/acoustic-connect/docs/react-native-integration) and the [sample app walk-through](https://developer.goacoustic.com/acoustic-connect/docs/build-a-sample-react-native-app).