Integrate the Connect library into your mobile application
The Connect SDK is a library that captures visitors' interactions with mobile applications. You can integrate the library into your app and track the findings in the Acoustic Connect interface.
Note
New to Connect? Install our preconfigured sample app and explore the implementation faster.
Requirements
- Acoustic Connect. To use the Connect SDK, your company must have an active Connect subscription of the Premium or Ultimate level. Proper credentials are required for each app (see Generate Connect credentials for integration).
- Development environment. To integrate the SDK into a native Android app, you need Android Studio.
- Mobile app compatibility. The SDK can capture user experience data on end users' devices running Android 5.0 (API level 21) or later.
- Acoustic Connect. To use the Connect SDK, your company must have an active Connect subscription of the Premium or Ultimate level. Proper credentials are required for each app (see Generate Connect credentials for integration).
- Development environment. You can integrate the Connect SDK into native iOS applications build on Swift and Objective-C. You will need Xcode 15 with Command Line Tools.
- Mobile app compatibility. The library can capture user experience data on end users' devices running iOS 12 and later. On iPadOS, only single-window applications are supported.
Warning
We offer limited support for iPad apps with a multi-window architecture. The Connect SDK captures data from such apps and makes it available for analytics, but session replays may not work correctly.
- Acoustic Connect. To use the Connect SDK, your company must have an active Connect subscription of the Premium or Ultimate level. Proper credentials are required for each app (see Generate Connect credentials for integration).
- Development environment. To integrate the SDK into your app, you need a standard Flutter environment. Supported versions: 3.3.0 - 3.22.2.
- Mobile app compatibility. The Connect SDK can function on end users' devices running Android 5.0 (API level 21) - Android 14 (API level 34). Supported iOS versions - 13.0 and later.
- Acoustic Connect. To use the Connect SDK, your company must have an active Connect subscription of the Premium or Ultimate level. Proper credentials are required for each app (see Generate Connect credentials for integration).
- Development environment. To integrate the SDK into your app, you need a standard React Native environment. Supported versions: 0.72.6 and later. Only older JSC bridge architecture is supported. Expo applications are not supported unless they are ejected as native applications.
- Mobile app compatibility. The library can function on end users' devices running Android 5.0 (API level 21) - Android 14 (API level 34). Supported iOS versions - 13.0 and later.
Prerequisites (Android only)
Before you get down to the integration, make sure the following conditions are met:
- AndroidManifest.xml has the following required permissions:
<!-- Required permissions -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!-- Recommended permissions: location -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
- Your Jetpack Compose project has the
NavController
class. The same navigation controller instance must be used throughout the navigation hierarchy.
Initial setup
- In the app-level build.gradle file, edit the Dependencies section to support the Connect SDK.
dependencies {
implementation("io.github.go-acoustic:connect:10.4.28")
}
- Synchronize the project.
- To initialize the SDK, add the following snippet to the Activity class. Replace
855e660c38824b4680602c6ac2a00zzz
with your application key andhttps://lib-us-2.brilliantcollector.com/collector/collectorPost
with your endpoint URL.
// Initialize Connect SDK
Connect.init(application)
// Enable Connect SDK
Connect.enable(
"855e660c38824b4680602c6ac2a00zzz",
"https://lib-us-2.brilliantcollector.com/collector/collectorPost"
)
- Add the Gesture hook to Base Activity.
override fun dispatchTouchEvent(e: MotionEvent?): Boolean {
Connect.dispatchTouchEvent(this, e)
return super.dispatchTouchEvent(e)
}
- Open the version catalog file (
gradle/libs.versions.toml
). Add Connect to the[versions]
and[libraries]
blocks.
[versions]
connect = "10.4.28"
[libraries]
connect = { module = "io.github.go-acoustic:connect", version.ref = "connect" }
- In the app-level build file (build.gradle.kts), update the
dependencies
block to support the Connect library.
implementation(libs.connect)
- Synchronize the project.
- Open the main entry point of the app and add an import statement for
ConnectWrapper
(a function that wraps around the UI tree of your app).
import com.acoustic.connect.android.connectmod.composeui.ConnectComposeUI.Companion.ConnectWrapper
- Customize the
ConnectWrapper
function for your app.
// Connect SDK Wrapper init with app key and post message URL
ConnectWrapper(
navController = navController,
appKey = "your_key",
postMessageURL = "your_endpoint_url"
){
Parameter | Values | Required? | Definition |
---|---|---|---|
navController | navController or appState.navController | Required | The type of navigation controller |
appKey | String | Required | The application key generated for the current app in Connect |
postMessageURL | String | Required | The endpoint associated with your Connect subscription |
- Integrate
ConnectWrapper
intonavController
. It is important that you placeConnectWrapper
at the root level of your app's composition.
ConnectWrapper integration examples
There are different ways to integrate ConnectWrapper
with your navigation setup. Choose the approach that best fits the app architecture.
If your app uses a direct navigation controller, add the ConnectWrapper
function right after you call rememberNavController()
. The app content must be inside. For example, Google's official Sunflower app that we use for demo purposes has a direct navigation controller.
fun YourApp() {
val navController = rememberNavController()
ConnectWrapper(
navController = navController,
appKey = "your_key",
postMessageURL = "your_endpoint_url"
) {
// Your app content
YourNavHost(navController = navController)
}
}
For better state management and testing, hoist navController
to a state holder. Google's official Now in Android is an example of such an app.
class YourAppState(val navController: NavHostController) {
// Other state management...
}
fun rememberYourAppState(navController: NavHostController = rememberNavController()): YourAppState {
return remember(navController) { YourAppState(navController) }
}
fun YourApp() {
val appState = rememberYourAppState()
ConnectWrapper(
navController = appState.navController,
appKey = "your_key",
postMessageURL = "your_endpoint_url"
) {
// Your app content using appState
}
}
If your app uses multiple navigation graphs, use the following approach.
fun YourApp() {
val navController = rememberNavController()
ConnectWrapper(
navController = navController,
appKey = "your_key",
postMessageURL = "your_endpoint_url"
) {
NavHost(navController = navController, startDestination = "main") {
// Your navigation graph
}
}
}
And here is a less typical example from an app with multiple back stack support.
fun YourApp() {
val navController = rememberNavController()
// Configure back stack behavior
val configuration =
NavHostController.Configuration(
navigatorProvider = navController.navigatorProvider,
backStackBehavior = BackStackBehavior.MULTIPLE_BACK_STACKS
)
ConnectWrapper(
navController = navController,
appKey = "your_key",
postMessageURL = "your_endpoint_url"
) {
// Your multi-stack navigation
}
}
Note
Need a refresher? Here is an official article explaining Jetpack navigation - Define routes and create a NavHostController.
Option A: CocoaPods
You can add the Connect SDK to your iOS app using the CocoaPods dependency manager. This option requires a recent version of CocoaPods.
Here are steps to follow:
- If you don't have a Podfile in your Xcode project directory, create one.
- Open the Podfile in a text editor and make sure the iOS version is 12.0 or later. Then uncomment
use_frameworks!
. - In the same Podfile, set
pod
to eitherAcousticConnect
orAcousticConnectDebug
, depending on the build you want to use.
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '12.0'
target 'SwiftUIMindBlowing' do
use_frameworks!
pod 'AcousticConnect'
end
- In a terminal emulator, navigate to your project directory.
- Install the pods. Make sure the command is completed with no errors. If you get an error, run the same command with the
--verbose
option and share the error log with our services team.
pod install
Important notes:
- Sometimes CocoaPods fails to load the latest version. So you may need to pull it using
pod update
. - If you get a warning message after running
pod install
, see our help article Removing CocoaPods warnings during integration.
Option B: Swift Package
You can add the Connect iOS SDK as a Swift Package.
- In your Xcode project, go to File > Add Package Dependencies.
- Search for
https://github.com/go-acoustic/Connect-SP
. For the debug build, replaceConnect-SP
withConnectDebug-SP
. Never use both versions in the same project.
- Select the target to add the library to.
Option C: Carthage
You can add the Connect iOS SDK to your app using the Carthage dependency manager.
- Create a Cartfile in your Xcode project directory if you don't have one yet.
touch Cartfile
- Open the Cartfile in a text editor and add the following lines for the release build. To add the debug build, update the file names: instead of EOCore.json use EOCoreDebug.json, instead of Tealeaf.json use TealeafDebug.json and instead of Connect.json use ConnectDebug.json.
binary "https://raw.githubusercontent.com/go-acoustic/EOCore/master/EOCore.json"
binary "https://raw.githubusercontent.com/go-acoustic/Tealeaf/master/Tealeaf.json"
binary "https://raw.githubusercontent.com/go-acoustic/Connect/master/Connect.json"
Warning
Never use the release and debug builds together in the same project.
- From the main project directory, run the command
carthage update --use-xcframeworks
. Make sure it completes without errors. - In a file manager, navigate to
/Carthage/Build
inside your project directory and select all three bundles.
- In your Xcode project, select the primary project target. Drag and drop the bundles to Frameworks, Libraries, and Embedded Content. Select Embed & Sign for each bundle.
- Switch to the Build Phases tab and make sure all three appear under Embed Frameworks. If they don't, you will need to add them as frameworks.
- Rebuild the project.
- From the root project directory, run the following commands.
flutter pub add connect_flutter_plugin
flutter pub get
- Open
lib/main.dart
and add an import statement there:
import 'package:connect_flutter_plugin/connect_flutter_plugin.dart';
- To wrap the Connect library over your app, add another statement to
lib/main.dart
. ReplaceFormApp
with the name of your app.
runApp(Connect(child: const FormApp()));
You can use NPM or Yarn. Run either of the following commands from the root project directory. It will add the Connect library to the package.json in your React Native project.
NPM command:
npm i react-native-acoustic-connect
Yarn command:
yarn add react-native-acoustic-connect
After that, open ConnectConfig.json in the root project directory and update the AppKey
and PostMessageUrl
parameters in it.
Required configuration
- If your project is built on SwiftUI, make sure it contains the AppDelegate file.
- Add the following code to AppDelegate. Replace
app_key
andendoint_url
with the credentials issued for your organization.
import Connect
import EOCore
import Tealeaf
import UIKit
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let connectApplicationHelperObj = ConnectApplicationHelper()
// Enable library to load configuration settings
let appKey: String = "app_key"
let postMessageURL: String = "endpoint_url"
connectApplicationHelperObj.enableFramework(appKey, withPostMessageUrl: postMessageURL)
return true
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
// MARK: UISceneSession Lifecycle
func application(
_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions
) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(
name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(
_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>
) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
- If you have installed the debug version, update your project scheme by adding three environment variables with the value of
1
:EODebug
,CONNECT_DEBUG
andTLF_DEBUG
.
Important:
- Never use the release and beta builds together in the same project.
- When reporting an issue to our support team, always attach your debug log. It speeds up troubleshooting.
- Open the AppDelegate.m file in your project.
- Add 2 import statements to the header.
@import Tealeaf;
@import Connect;
- Add the following code to the
didFinishLaunchingWithOptions
function. Replaceapp_key
andendpoint_url
with your Connect credentials.
[[TLFApplicationHelper sharedInstance] enableTealeafFramework:@"app_key" withPostMessageUrl:@"endpoint_url"];
- If you have installed the debug version, add three variables with the value of
1
to the project scheme:EODebug
,CONNECT_DEBUG
andTLF_DEBUG
.
- In the root project directory, open ConnectConfig.json and update the
AppKey
andPostMessageUrl
parameters in it. - If necessary, update other parameters (the list is available below).
- Navigate to the root project directory and run the Connect Command Line Tool.
cd <YOUR_PROJECT_PATH>
dart run $HOME/connect_cli/bin/connect_cli.dart
Important
Make sure you run this command each time after updating ConnectConfig.json.
Here is a full list of configuration parameters you may need during the initial installation.
Parameter | Values | Required? | Description |
---|---|---|---|
AppKey | String | Required | The application key generated for your Flutter app |
PostMessageUrl | String | Required | The endpoint URL associated with your Connect subscription |
KillSwitchUrl | String | Optional | For production, you will need to replace the default application key at the end of the URL with your application key. You can do it now, but this is not required. |
useRelease | Boolean. The default value is true . | Optional | Set the value to false to switch to the latest beta version of the library. It contains debug information. |
iOSVersion | String | Optional | Under the hood, the Connect Flutter SDK is a wrapper for two Connect SDKs: iOS and Android. Using this parameter, you can downgrade the iOS SDK to an older version. |
AndroidVersion | String | Optional | Using this parameter, you can downgrade the Android SDK to an older version. |
What's next?
Now you can build and run your app.
Final project preparation
Hybrid projects may take a few additional steps.
Launch task creation (optional)
Our sample app contains a hidden directory (.vscode). The files in it integrate the above steps into a pre-build flow. You can re-use this directory for your app.
- Create the same directory in the root of your app.
- Add the prelaunch task labeled Run Connect CLI.
- Copy tasks.json from our sample app.
- In your tasks.json, update the
args
section with your application key and endpoint URL.
Material navigation and navigation widgets
Does your app use Material navigation or any of the following widgets: TabBar
, TabBarView
or BottomNavigationBar
? Logging screen change events for them requires some additional setup.
For example, if a BottomNavigationBar
is used without a proper Route-based navigation setup (e.g., by showing and hiding widgets within the same screen), LoggingNavigatorObserver
won't be able to log navigation events.
To log navigation events for these types of widgets, add the following code snippets when the user interacts with these widgets (e.g., onTap
or onChanged
callback functions).
PluginTealeaf.logScreenLayout('logicalPageName');
If your project uses React Navigation 5, make the following changes to App.js (or another file that serves as the main component of your app). This is necessary for correct screen capturing.
- Add an import statement for Connect.
import { Connect } from 'react-native-acoustic-connect';
- Wrap the navigation container into
<Connect>
.
export default () => {
const navigationRef = useRef();
return (
<Connect>
<NavigationContainer ref={navigationRef}>
<StackNav/>
</NavigationContainer>
</Connect>
);
};
Here is a sample file for your reference.
If your React Native project doesn't use React Navigation, make the following changes to App.js (or another file that serves as the main component of your app). This is necessary for correct screen capturing.
- Add an import statement for Connect.
import {NativeModules, findNodeHandle} from 'react-native';
const Connect = NativeModules.RNCxa;
- Add
Connect.setCurrentScreenName("HomePage");
.
Here is an example:
import React, { Component } from "react";
import { Container, Header, Title, Content, Button, Left, Right, Body, Text } from "native-base";
import styles from "./styles";
// Add import
import {NativeModules, findNodeHandle} from 'react-native';
const Connect = NativeModules.RNCxa;
class Header1 extends Component {
render() {
Connect.setCurrentScreenName("HomePage");
return (
<Container style={styles.container}>
<Header>
<Left />
<Body>
<Title>Header</Title>
</Body>
<Right />
</Header>
<Content padder>
<Button onPress={() => this.props.navigation.goBack()}>
<Text>Back</Text>
</Button>
</Content>
</Container>
);
}
}
export default Header1;
Troubleshooting
If there's a build issue in a Flutter project or the Connect Flutter plugin is not using the latest SDK, run the following commands.
cd android && ./gradlew build --refresh-dependencies
cd ios && pod update
Further steps
Updated 8 days ago