Important
Requirements:
- Flutter: ">=3.3.0"
- SDK: ">=2.18.0 < 4.0.0"
Note
These instructions assume prior knowledge of Flutter integrated into your existing native app as a library or module.
For native applications using Flutter components, use this guide to track your entire app.
- Add the Pendo dependency
- Android integration
- iOS integration
- Sending a track event from the dart side
- Limitations
- Developer documentation
- Troubleshooting
In the pubspec.yaml
file, add the Pendo plugin under the dependencies section:
# make sure you are using the latest version. This is just an example:
pendo_sdk: ^3.4.0
In the terminal, run: flutter pub get
Important
Jetpack Compose is supported by our track events only solution. We plan to add codeless support in the future.
Important
Requirements:
- Android Gradle Plugin
7.2
or higher - Kotlin version
1.9.0
or higher - JAVA version
11
or higher - minSdkVersion
21
or higher - compileSDKVersion
33
or higher
Note
The API Key
can be found in your Pendo Subscription Settings in App Details.
- Add the Pendo repository to android/build.gradle:
-
Add the Pendo Repository to the repositories section under the allprojects section or to the settings.gradle if using dependencyResolutionManagement:
allprojects { repositories { maven { url = uri("https://software.mobile.pendo.io/artifactory/androidx-release") } mavenCentral() } }
-
Add Pendo as a dependency to android/build.gradle file:
dependencies { implementation group:'sdk.pendo.io' , name:'pendoIO', version:'3.4.+', changing:true }
-
In the application AndroidManifest.xml file:
Add the following<uses-permission>
to the manifest in the<manifest>
tag:<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
-
Using ProGuard / R8
-
If you are using ProGuard, the rules that need to be added to ProGuard can be found here: pendo-proguard.cfg.
-
If you are using ProGuard(D8/DX only) to perform compile-time code optimization, and have
{Android SDK Location}/tools/proguard/proguard-android-optimize.txt
, add!code/allocation/variable
to the-optimizations
line in yourapp/proguard-rules.pro
file. The optimizations line should look like this:
-optimizations *other optimizations*,!code/allocation/variable
Init the SDK from the native and register the plugin:
package io.tsh.flutterloginembedding
import android.app.Application
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.embedding.engine.FlutterEngineCache
import io.flutter.embedding.engine.dart.DartExecutor
import io.flutter.plugins.GeneratedPluginRegistrant
import sdk.pendo.io.Pendo
class App : Application() {
companion object {
const val FLUTTER_ENGINE_ID = "newLoginEngine"
}
override fun onCreate() {
super.onCreate()
// Instantiate a FlutterEngine and
val flutterEngine = FlutterEngine(this)
// Execute the Dart code to pre-warm the FlutterEngine
flutterEngine.dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)
// Cache the FlutterEngine to be used by FlutterActivity
FlutterEngineCache
.getInstance()
.put(FLUTTER_ENGINE_ID, flutterEngine)
// connect to Pendo's server
Pendo.setup(
this,
"YOUR_API_KEY_HERE",
null, // PendoOptions (use only if instructed by Pendo support)
null // PendoPhasesCallbackInterface (Optional)
);
// start a session
val visitorId = "VISITOR-UNIQUE-ID"
val accountId = "ACCOUNT-UNIQUE-ID"
val visitorData = HashMap<String, Any>()
visitorData.put("age", 27)
visitorData.put("country", "USA")
val accountData = HashMap<String, Any>()
accountData.put("Tier", 1)
accountData.put("Size", "Enterprise")
Pendo.startSession(
visitorId,
accountId,
visitorData,
accountData)
// Connect the plugin
GeneratedPluginRegistrant.registerWith(flutterEngine)
}
}
Tip
To begin a session for an anonymous visitor, pass null
or an empty string ''
as the visitor id. You can call the startSession
API more than once and transition from an anonymous session to an identified session (or even switch between multiple identified sessions).
Note
The Scheme ID
can be found in your Pendo Subscription Settings in App Details.
This step enables guide testing capabilities.
Add the following activity to the application AndroidManifest.xml in the <Application>
tag:
<activity android:name="sdk.pendo.io.activities.PendoGateActivity" android:launchMode="singleInstance" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="YOUR_SCHEME_ID_HERE"/>
</intent-filter>
</activity>
- Test using Android Studio:
Run the app while attached to the Android Studio.
Review the Android Studio logcat and look for the following message:
Pendo SDK was successfully integrated and connected to the server.
- In the Pendo UI, go to Settings>Subscription Settings.
- Select the Applications tab and then your application.
- Select the Install Settings tab and follow the instructions under Verify Your Installation to ensure you have successfully integrated the Pendo SDK.
- Confirm that you can see your app as Integrated under subscription settings.
Important
SwiftUI codeless solution is fully supported from iOS 15
.
SwiftUI screen navigation tracking is available from iOS 13
.
Important
Requirements:
- Deployment target of
iOS 11
or higher - Swift Compatibility
5.7
or higher - Xcode
14
or higher
In your native app folder, run: pod install
Note
The API Key
can be found in your Pendo Subscription Settings in App Details.
Swift Instructions - Click to expand or collapse
Using Swift, to access the PendoSDK.h, include it in the Bridging-Header.h of your app, adding:
#import "PendoFlutterPlugin.h"
Setup the SDK in the native code and register the plugin as follows:
import UIKit
import Flutter
import FlutterPluginRegistrant
import Pendo
@UIApplicationMain
class AppDelegate: FlutterAppDelegate {
lazy var flutterEngine = FlutterEngine(name: "my flutter engine")
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// connect to Pendo's server
PendoManager.shared().setup("YOUR_API_KEY_HERE")
// start a session
let visitorId = "John Doe"
let accountId = "ACME"
let visitorData: [String : any Hashable] = ["age": 27, "country": "USA"]
let accountData: [String : any Hashable] = ["Tier": 1, "size": "Enterprise"]
PendoManager.shared().startSession(visitorId, accountId:accountId, visitorData:visitorData, accountData:accountData)
// Run the default Dart entrypoint with a default Flutter route
flutterEngine.run()
// Connect the plugin to the iOS platform code
GeneratedPluginRegistrant.register(with: self.flutterEngine)
// Register the Pendo Plugin
PendoFlutterPlugin.registerWithRegistry(self.flutterEngine)
return super.application(application, didFinishLaunchingWithOptions: launchOptions);
}
}
Objective-C Instructions - Click to expand or collapse
Setup the SDK in the native code in your AppDelegate
file and register the plugin as follows:
@import UIKit;
@import Flutter;
@import Pendo;
#import <FlutterPluginRegistrant/GeneratedPluginRegistrant.h>
#import "PendoFlutterPlugin.h"
#import "AppDelegate.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// connect to Pendo's server
[[PendoManager sharedManager] setup:@"YOUR_API_KEY_HERE"];
// start a session
[[PendoManager sharedManager] startSession:@"John Doe" accountId:@"ACME" visitorData:@{@"age": @27, @"country": @"USA"} accountData:@{@"Tier": @1, @"size": @"Enterprise"}];
// Run the default Dart entrypoint with a default Flutter route
FlutterEngine *flutterEngine = [[FlutterEngine alloc] initWithName:@"my flutter engine"];
[flutterEngine run];
// Connect the plugin to the iOS platform code
[GeneratedPluginRegistrant registerWithRegistry:flutterEngine];
// Register the Pendo Plugin
[PendoFlutterPlugin registerWithRegistry:flutterEngine];
return YES;
}
@end
Tip
To begin a session for an anonymous visitor, pass null
or an empty string ''
as the visitor id. You can call the startSession
API more than once and transition from an anonymous session to an identified session (or even switch between multiple identified sessions).
Note
The Scheme ID
can be found in your Pendo Subscription Settings in App Details.
These steps enable guide testing capabilities.
-
Add Pendo URL scheme to info.plist file:
Under App Target > Info > URL Types, create a new URL by clicking the + button.
Set Identifier to pendo-pairing or any name of your choosing.
Set URL Scheme toYOUR_SCHEME_ID_HERE
. -
To enable pairing from the device:
In the AppDelegate file add or modify the openURL function:
Swift Instructions - Click to expand or collapse
import Pendo @UIApplicationMain class AppDelegate: FlutterAppDelegate { override func application(_ app: UIApplication,open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { if url.scheme?.range(of: "pendo") != nil { PendoManager.shared().initWith(url) return true } // your code here... return true } }
Objective-C Instructions - Click to expand or collapse
@import Pendo; //your code - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { if ([[url scheme] containsString:@"pendo"]) { [[PendoManager sharedManager] initWithUrl:url]; return YES; } // your code here ... return YES; }
- Test using Xcode:
Run the app while attached to Xcode.
Review the Xcode console and look for the following message:
Pendo Mobile SDK was successfully integrated and connected to the server.
- In the Pendo UI, go to Settings>Subscription Settings.
- Select the Applications tab and then your application.
- Select the Install Settings tab and follow the instructions under Verify Your Installation to ensure you have successfully integrated the Pendo SDK.
- Confirm that you can see your app as Integrated under subscription settings.
Configure Pendo Track Events to capture analytics to notify Pendo of analytics events. In the application files where you want to track an event, add the following code:
import 'package:pendo_sdk/pendo_sdk.dart';
await PendoSDK.track('name', { 'firstProperty': 'firstPropertyValue', 'secondProperty': 'secondPropertyValue'});
- Android native API documentation available here.
- iOS native API documentation available here.
- Flutter plugin API documentation available here.
- For technical issues, please review open issues or submit a new issue.
- Release notes can be found here.
- For additional documentation, visit our Help Center Mobile Section.