├── .gitignore ├── LICENSE.md ├── Package.swift ├── other └── flutter-notes-known-issues-limitations.md ├── migration-docs ├── README.md ├── xamarin-forms-2.x-to-3.x-migration.md ├── maui-2.x-to-3.x-migration.md ├── flutter-2.x-to-3.x-migration.md ├── react-native-2.x-to-3.x-migration.md ├── android-2.x-to-3.x-migration.md └── ios-2.x-to-3.x-migration.md ├── .github └── ISSUE_TEMPLATE │ └── bug_report.md ├── benchmarks ├── FlutterPerformanceBenchmarks.md └── NativePerformanceBenchmarks.md ├── android └── pnddocs │ ├── android_sdk_manual_installation.md │ ├── pendo-proguard.cfg │ ├── expo_rnn-android.md │ ├── xamarin_forms-android.md │ ├── expo_rn-android.md │ ├── expo_router-android.md │ ├── xamarin_maui-android.md │ ├── rnn-android.md │ ├── rn-android.md │ ├── native-android.md │ └── flutter-android.md ├── README.md ├── ios └── pnddocs │ ├── expo_rnn-ios.md │ ├── xamarin_forms-ios.md │ ├── expo_rn-ios.md │ ├── expo_router-ios.md │ ├── xamarin_maui-ios.md │ ├── rnn-ios.md │ ├── rn-ios.md │ └── flutter-ios.md └── api-documentation ├── flutter-apis.md ├── xamarin-forms-apis.md └── xamarin-maui-apis.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .DS_Store 3 | .build/ 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The software is governed by the Pendo License Terms and Conditions available at https://www.pendo.io/legal/license-terms-and-conditions-may-2020/ (including any successor site). 2 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Pendo", 8 | platforms: [ 9 | .iOS(.v11) 10 | ], 11 | products: [ 12 | .library( 13 | name: "Pendo", 14 | targets: ["Pendo"]) 15 | ], 16 | dependencies: [ 17 | ], 18 | targets: [ 19 | .binaryTarget( 20 | name: "Pendo", 21 | url: "https://software.mobile.pendo.io/artifactory/ios-sdk-release/3.9.2.10806/pendo-ios-sdk-xcframework.3.9.2.10806.zip", 22 | checksum: "753fdb244c26f9c7ea84635e0a03853f06677bb98d6f7d1a2c322ed7db196907" 23 | ), 24 | ] 25 | ) 26 | -------------------------------------------------------------------------------- /other/flutter-notes-known-issues-limitations.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Navigation Libraries 4 | The Page recognition solution supports the standard Flutter Navigator, GoRouter and AutoRoute libraries. Integration with additional navigation frameworks is planned for future releases. 5 | 6 | ## Clickable Widgets 7 | Our implementation supports basic touch interactions (touchDown and touchUp) on a range of standard Flutter widgets, including:
8 | InkResponse, InkWell, GestureDetector
9 | ButtonStyleButton, FloatingActionButton, IconButton, MaterialButton
10 | PopupMenuButton, DropdownButton, Checkbox, Chip, ChoiceChip, FilterChip, InputChip, Switch, Radio, ListTile
11 | TabBar, BottomNavigationBar, SelectableText, TextField
12 | 13 | ## Known Issues 14 | Drag and Swipe gestures support is planned for future releases. 15 | -------------------------------------------------------------------------------- /migration-docs/README.md: -------------------------------------------------------------------------------- 1 | # Migrating from version 2.x to version 3.x 2 | 3 | >[!NOTE] 4 | >Xamarin iOS and Xamarin Android are no longer supported in 3.x. Please use the SDK for MAUI or Xamarin Forms. You can continue using your existing Android and iOS Pendo Apps, but make sure to pass in the correct API Key per platform and to update all of your tagged Pages. 5 | 6 | Follow our migration instructions to resolve breaking changes when upgrading from SDK version 2.x to version 3.x: 7 | 8 | - [Native Android](/migration-docs/android-2.x-to-3.x-migration.md) 9 | - [Native iOS](/migration-docs/ios-2.x-to-3.x-migration.md) 10 | - [React Native](/migration-docs/react-native-2.x-to-3.x-migration.md) (relevant for RN, RNN & Expo integrations) 11 | - [Xamarin Forms](/migration-docs/xamarin-forms-2.x-to-3.x-migration.md) 12 | - [MAUI](/migration-docs/maui-2.x-to-3.x-migration.md) 13 | - [Flutter](/migration-docs/flutter-2.x-to-3.x-migration.md) 14 | 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Platform + Version** 11 | e.g., IOS 16, Android 12 | 13 | **SDK Version** 14 | 15 | **Framework** 16 | e.g., Native, SwiftUI,
17 | React Native using React Navigation, 18 | React Native using React Native Navigation, 19 | Expo using React Navigation, 20 | Expo using React Native Navigation
21 | Xamarin, XamarinForms, Maui,
22 | Flutter 23 | 24 | **Describe the bug** 25 | A clear and concise description of what the bug is. 26 | 27 | **To Reproduce** 28 | Steps to reproduce the behavior: 29 | 1. Go to '...' 30 | 2. Click on '....' 31 | 3. Scroll down to '....' 32 | 4. See error 33 | 34 | **Expected behavior** 35 | A clear and concise description of what you expected to happen. 36 | 37 | **Logs** 38 | If applicable, please add crash logs OR pendo logs (can be turned on with `PendoManager.shared().setDebugMode(true)`) 39 | 40 | **Sample Code** 41 | Code snippet or Sample project 42 | 43 | **Additional context** 44 | Add any other context about the problem here. -------------------------------------------------------------------------------- /benchmarks/FlutterPerformanceBenchmarks.md: -------------------------------------------------------------------------------- 1 | ## Performance benchmarks 2 | 3 | These measurements of the SDK are captured using Pendo’s testing applications and may differ among applications, depending on their screen complexity and user interaction. 4 | 5 | ### SDK performance 6 | 7 | | | Size Impact | Memory Impact | CPU Impact\* | 8 | | :---: | :---: | :---: | :---: | 9 | | Flutter | 103KB\*\* | (~) 60-200KB | LOW | 10 | 11 | \* Slight CPU impact may occur during app launch or UI-intensive operations. 12 | 13 | \*\* 103KB reffers to the Flutter plugin size while iOS native SDK size is ~6MB, Android native SDK size is ~3MB. 14 | 15 | ### SDK network usage 16 | **Outgoing traffic** 17 | 18 | The analytics captured by the SDK include starting a session, the application state (foreground and background), screen changing, clicks, guide events, and manual track events. 19 | 20 | The size of each analytic event varies from 1KB to 9KB. 21 | 22 | 23 | \* These benchmarks relate to the performance of Pendo's Flutter plugin. To see the native benchmark behind it, please visit the [Native benchmarks](NativePerformanceBenchmarks.md) page. -------------------------------------------------------------------------------- /migration-docs/xamarin-forms-2.x-to-3.x-migration.md: -------------------------------------------------------------------------------- 1 | # Xamarin Forms migration from version 2.x to version 3.x 2 | 3 | The following changes are required: 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 62 | 63 |
Component / API Instructions
Library import 16 | 17 | Replace the NuGet package `PendoSDKXamarin` with the NuGet package `pendo-xamarin-forms`. 18 | 19 |
Minimum Xamarin.Forms version 29 | 30 | 2.x (deprecated): 31 | `5.0.0.0` 32 |
33 | 3.x: 34 | `5.0.0.2612` 35 |
Minimum
Kotlin version

(Relevant for Android apps only)
43 | 44 | 2.x (deprecated): `1.7.20` 45 |
46 | 3.x: `1.9.0` 47 | 48 |
Target
Android version

(Relevant for Android apps only)
56 | 57 | 2.x (deprecated): `API Level 31 (v12.0)` 58 |
59 | 3.x: `API Level 33 (v13.0)` 60 | 61 |
-------------------------------------------------------------------------------- /android/pnddocs/android_sdk_manual_installation.md: -------------------------------------------------------------------------------- 1 | # Pendo Android SDK manual installation 2 | 3 | If you are having problems installing the SDK, please follow these steps: 4 | 5 | 1. Download the Pendo SDK (we always recommend taking the latest) here. 6 | 7 | 2. Unzip the downloaded file. 8 | 9 | 3. Add the local directory to the gradle file or to the settings.gradle if using dependencyResolutionManagement: 10 | 11 | ```java 12 | repositories { 13 | maven { 14 | url = uri("/path/to/local/file") 15 | } 16 | } 17 | ``` 18 | 19 | 4. Specify the version number for the Pendo dependency in the gradle file.
For example, for version 3.9.0.x it should look like this: 20 | 21 | ```java 22 | implementation (group:'sdk.pendo.io' , name:'pendoIO', version:'3.9.0.x', changing:true) 23 | ``` 24 | 25 | ## Developer documentation 26 | 27 | - View our [API documentation](/api-documentation/native-android-apis.md). 28 | 29 | 30 | ## Troubleshooting 31 | 32 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 33 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 34 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 35 | -------------------------------------------------------------------------------- /benchmarks/NativePerformanceBenchmarks.md: -------------------------------------------------------------------------------- 1 | ## Performance benchmarks 2 | 3 | These measurements of the SDK are captured using Pendo’s testing applications and may differ among applications, depending on their screen complexity and user interaction. 4 | 5 | ### SDK performance 6 | 7 | | | Size Impact\* | Battery Impact | Memory Impact | CPU Impact\*\* | 8 | | :---: | :---: | :---: | :---: | :---: | 9 | | Android | +2.7MB | Low | (~) +27MB | Low | 10 | | iOS | +5.7MB | Low | (~) +4MB | Low | 11 | 12 | \* Size impact regarding the release builds, available through Google Play or App Store. 13 |
14 | \*\* Slight CPU impact may occur during app launch or UI-intensive operations. 15 | 16 | ### SDK network usage 17 | 18 | The Pendo SDK network traffic consists of two parts: 19 | * The SDK initialization process to establish a connection between the device and Pendo’s server, starting a session and fetching any guides relevant to the session. 20 | * During the session, ongoing analytics are sent in bulk from the device. 21 | 22 | **Incoming traffic** (during the session startup) 23 | 24 | | No guides | A single guide with three steps | A single guide with nine steps | 25 | | :---: | :---: | :---: | 26 | | Up to 40KB | Up to 64KB | Up to 90KB | 27 | 28 | Network requests are executed in parallel, prioritizing guides with higher priority to be downloaded first and becoming available earlier during the initialization process of the session. For example, guides with an app launch trigger will be available immediately, while lower-priority guides may take a few additional seconds to be available during the session. 29 | 30 | **Outgoing traffic** 31 | 32 | The analytics captured by the SDK include starting a session, the application state (foreground and background), screen changing, clicks, guide events, and manual track events. The size of each analytic event varies from 1KB to 6.5KB. 33 | 34 | **Network usage example** 35 | 36 | A session with a single guide including four steps, 6 session analytics, 42 page transitions, 65 Feature clicks, 13 guide events 37 | and 3 track events, recorded ~120KB of data received and ~320KB of data transmitted. 38 | 39 | -------------------------------------------------------------------------------- /migration-docs/maui-2.x-to-3.x-migration.md: -------------------------------------------------------------------------------- 1 | # MAUI migration from version 2.x to version 3.x 2 | 3 | The following changes are required: 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 115 | 116 |
Component / API Instructions
.NET 16 | 17 | 2.x (deprecated): `.NET 6` 18 |
19 | 3.x: `.NET 7` or `.NET 8` 20 | 21 |
Minimum
Kotlin version

(Relevant for Android apps only)
31 | 32 | 2.x (deprecated): `1.7.20` 33 |
34 | 3.x: `1.9.0` 35 | 36 |
Target
Android version

(Relevant for Android apps only)
44 | 45 | 2.x (deprecated): `API Level 31 (v12.0)` 46 |
47 | 3.x: `API Level 33 (v13.0)` 48 | 49 |
Obtain the
Pendo instance
58 | 59 | Obtain the shared project `Pendo` instance using the `PendoServerFactory` instead of creating a new `PendoInterface` instance. 60 | 61 | 2.x (deprecated): 62 | 63 | ```C# 64 | PendoInterface pendo = new PendoInterface(); 65 | ``` 66 | 67 | 3.x: 68 | 69 | ```C# 70 | IPendoService pendo = PendoServiceFactory.CreatePendoService(); 71 | 72 | // if your app supports additional Platforms other than iOS and Android, verify the Pendo instance is not null 73 | if (pendo != null) { 74 | 75 | // the rest of your Pendo code 76 | 77 | } 78 | ``` 79 | 80 |
Register
Pendo Effects
88 | 89 | 2.x (deprecated): N/A 90 |
91 | 3.x: 92 | If your app is using Gestures, you must upgrade to SDK version 3.1 or above and then register Pendo Effects (PendoRoutingEffect, PendoPlatformEffect) in your MauiProgram.cs file as shown in the code below. 93 | 94 | ```C# 95 | ... 96 | using PendoMAUIPlugin; 97 | ... 98 | 99 | public static class MauiProgram 100 | { 101 | public static MauiApp CreateMauiApp() 102 | { 103 | var builder = MauiApp.CreateBuilder(); 104 | builder.UseMauiApp(); 105 | 106 | builder.ConfigureEffects(effects => 107 | { 108 | effects.Add(); 109 | }); 110 | return builder.Build(); 111 | } 112 | } 113 | ``` 114 |
-------------------------------------------------------------------------------- /android/pnddocs/pendo-proguard.cfg: -------------------------------------------------------------------------------- 1 | # Keep all non obfuscated classes under Pendo SDK core code in .aar 2 | -keep class sdk.pendo.io.** { *; } 3 | 4 | # Keep all non obfuscated classes under external libs in .aar 5 | -keep class external.sdk.pendo.io.** { *; } 6 | 7 | # Keep all views - names and listed methods for 8 | # dynamic views initialisation, predicate rules... 9 | -keep public class * extends android.view.View { 10 | public (android.content.Context); 11 | public (android.content.Context, android.util.AttributeSet); 12 | public (android.content.Context, android.util.AttributeSet, int); 13 | public void set*(...); 14 | } 15 | 16 | # Keep Fragments for their names we use in page identification screenId 17 | -keepnames public class * extends android.support.v4.app.Fragment 18 | -keepnames public class * extends android.app.Fragment 19 | -keepnames public class * extends androidx.fragment.** 20 | -dontwarn external.sdk.pendo.io.glide.R$id 21 | -dontwarn external.sdk.pendo.io.org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 22 | -dontwarn external.sdk.pendo.io.org.conscrypt.Conscrypt$Version 23 | -dontwarn external.sdk.pendo.io.org.conscrypt.Conscrypt 24 | -dontwarn external.sdk.pendo.io.org.conscrypt.ConscryptHostnameVerifier 25 | -dontwarn external.sdk.pendo.io.org.jetbrains.annotations.NotNull 26 | -dontwarn external.sdk.pendo.io.org.jetbrains.annotations.Nullable 27 | -dontwarn external.sdk.pendo.io.org.openjsse.javax.net.ssl.SSLParameters 28 | -dontwarn external.sdk.pendo.io.org.openjsse.javax.net.ssl.SSLSocket 29 | -dontwarn external.sdk.pendo.io.org.openjsse.net.ssl.OpenJSSE 30 | -dontwarn external.sdk.pendo.io.slf4j.impl.StaticLoggerBinder 31 | -dontwarn java.security.interfaces.EdECPrivateKey 32 | -dontwarn java.security.interfaces.EdECPublicKey 33 | -dontwarn java.security.interfaces.XECPrivateKey 34 | -dontwarn java.security.interfaces.XECPublicKey 35 | -dontwarn java.security.spec.EdECPoint 36 | -dontwarn java.security.spec.EdECPrivateKeySpec 37 | -dontwarn java.security.spec.EdECPublicKeySpec 38 | -dontwarn java.security.spec.NamedParameterSpec 39 | -dontwarn java.security.spec.XECPrivateKeySpec 40 | -dontwarn java.security.spec.XECPublicKeySpec 41 | -dontwarn javax.swing.** 42 | -dontwarn java.awt.** 43 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 44 | -dontwarn androidx.window.** 45 | -dontwarn com.google.api.client.http.** 46 | -dontwarn edu.umd.cs.findbugs.annotations.SuppressFBWarnings 47 | -dontwarn java.lang.invoke.StringConcatFactory 48 | 49 | #ParametrizedType ClassCastException error fix 50 | -keep,allowobfuscation,allowshrinking interface retrofit2.Call 51 | -keep,allowobfuscation,allowshrinking class retrofit2.Response 52 | -keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation 53 | 54 | # Gson uses generic type information stored in a class file when working with fields. Proguard 55 | # removes such information by default, so configure it to keep all of it. 56 | -keepattributes Signature 57 | 58 | # For using GSON @Expose annotation 59 | -keepattributes *Annotation* 60 | 61 | # Gson specific classes 62 | -dontwarn sun.misc.** 63 | 64 | # Application classes that will be serialized/deserialized over Gson 65 | -keep class external.sdk.pendo.io.gson.examples.android.model.** { ; } 66 | 67 | # Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory, 68 | # JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter) 69 | -keep class * extends external.sdk.pendo.io.gson.TypeAdapter 70 | -keep class * implements external.sdk.pendo.io.gson.TypeAdapterFactory 71 | -keep class * implements external.sdk.pendo.io.gson.JsonSerializer 72 | -keep class * implements external.sdk.pendo.io.gson.JsonDeserializer -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pendo Mobile SDK 2 | 3 | The Pendo Mobile SDK is a codeless library that collects analytics retroactively across all versions of your app. The SDK also provides the ability to display in-app messages, tooltips and multi-step walkthrough guides built using Pendo's Visual Design Studio. The SDK starts collecting analytics as soon as it is integrated. The integration requires minimal effort with a few lines of code. 4 | 5 | 6 | ## Integration instructions 7 | 8 | >[!NOTE] 9 | >The following integration instructions are relevant for SDK 3.0 or higher.
Follow our migration instructions to [upgrade from SDK 2.x to 3.0](/migration-docs/README.md) or refer to our [2.x integration instruction](https://github.com/pendo-io/pendo-mobile-sdk/blob/2.22.5/README.md). 10 | 11 | 12 | - Native: 13 | [Android](/android/pnddocs/native-android.md) | 14 | [iOS](/ios/pnddocs/native-ios.md) 15 | - React Native: 16 | - Using React Navigation: 17 | [Android](/android/pnddocs/rn-android.md) | 18 | [iOS](/ios/pnddocs/rn-ios.md) 19 | - Using React Native Navigation: 20 | [Android](/android/pnddocs/rnn-android.md) | 21 | [iOS](/ios/pnddocs/rnn-ios.md) 22 | - Using Expo with Expo Router: 23 | [Android](/android/pnddocs/expo_router-android.md) | 24 | [iOS](/ios/pnddocs/expo_router-ios.md) 25 | - Using Expo with React Navigation: 26 | [Android](/android/pnddocs/expo_rn-android.md) | 27 | [iOS](/ios/pnddocs/expo_rn-ios.md) 28 | - Using Expo with React Native Navigation 29 | [Android](/android/pnddocs/expo_rnn-android.md) | 30 | [iOS](/ios/pnddocs/expo_rnn-ios.md) 31 | - Xamarin Forms: 32 | [Android](/android/pnddocs/xamarin_forms-android.md) | 33 | [iOS](/ios/pnddocs/xamarin_forms-ios.md) 34 | - MAUI: 35 | [Android](/android/pnddocs/xamarin_maui-android.md) | 36 | [iOS](/ios/pnddocs/xamarin_maui-ios.md) 37 | - Flutter: 38 | [Android](/android/pnddocs/flutter-android.md) | 39 | [iOS](/ios/pnddocs/flutter-ios.md) | 40 | [Native with Flutter components](/other/native-with-flutter-components.md) 41 | 42 | For integration using signed metadata see: [JWT integration instructions](https://support.pendo.io/hc/en-us/articles/360039616892-Send-signed-metadata-with-JWT) 43 | 44 | 45 | ## API documentation 46 | 47 | - [Native Android](/api-documentation/native-android-apis.md) 48 | - [Native iOS](/api-documentation/native-ios-apis.md) 49 | - [React Native](/api-documentation/rn-apis.md) 50 | - [Xamarin Forms](/api-documentation/xamarin-forms-apis.md) 51 | - [MAUI](/api-documentation/xamarin-maui-apis.md) 52 | - [Flutter](/api-documentation/flutter-apis.md) 53 | 54 | 55 | ## Additional resources 56 | 57 | - [Release notes](https://developers.pendo.io/category/mobile-sdk/) 58 | - [Plan your mobile implementation](https://support.pendo.io/hc/en-us/articles/23527373013275-Plan-your-mobile-implementation) 59 | - [Supported Mobile Frameworks and OS Versions](https://support.pendo.io/hc/en-us/articles/360031861572-Supported-mobile-frameworks-and-OS-versions) 60 | - [Codeless tracking vs Track Events](https://support.pendo.io/hc/en-us/articles/360061487572-Codeless-tracking-vs-Track-Events) 61 | - [Using Pendo with hybrid apps](https://support.pendo.io/hc/en-us/articles/23804736263195-Use-Pendo-with-hybrid-apps) 62 | - [Configuring CNAME Hostnames](https://support.pendo.io/hc/en-us/articles/360047607631-Configure-CNAME-for-Pendo-Mobile) 63 | - [Work with dynamic content in your mobile app](https://support.pendo.io/hc/en-us/articles/24836902488219-Work-with-dynamic-content-in-your-mobile-app) 64 | - [Mobile offline support analytics](https://support.pendo.io/hc/en-us/articles/360043016412-Mobile-offline-support-for-analytics) 65 | 66 | 67 | Visit the [Mobile Resource Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation) For additional documentation. 68 | 69 | ## Troubleshooting 70 | 71 | - For technical issues, [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 72 | 73 | ## Performance benchmarks 74 | 75 | - [Native benchmarks](/benchmarks/NativePerformanceBenchmarks.md) 76 | - [Flutter benchmarks](/benchmarks/FlutterPerformanceBenchmarks.md) 77 | -------------------------------------------------------------------------------- /migration-docs/flutter-2.x-to-3.x-migration.md: -------------------------------------------------------------------------------- 1 | # Flutter migration from version 2.x to version 3.x 2 | 3 | 4 | Follow these instructions to resolve breaking changes in your app:: 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 213 | 214 |
Component / APIInstructions
Minimum
Flutter version

18 | 19 | 2.x (deprecated): `2.0.0 - 2.10.5` 20 |
21 | 3.x: `3.3.0` 22 | 23 |
Minimum
Dart version

31 | 32 | 2.x (deprecated): `2.12.0 - 2.16.2` 33 |
34 | 3.x: `2.18` 35 | 36 |
Minimum
JAVA version

(Relevant for Android apps only)
44 | 45 | 2.x (deprecated): `JAVA 8` 46 |
47 | 3.x: `JAVA 11` 48 | 49 |
Minimum
Kotlin version

(Relevant for Android apps only)
57 | 58 | 2.x (deprecated): `1.7.20` 59 |
60 | 3.x: `1.9.0` 61 | 62 |
initSDK 70 | 71 | Replace `initSDK` by calling `setup` and then `startSession`. 72 | 73 | 2.x (deprecated): 74 | 75 | ```dart 76 | // set session paramaters 77 | final dynamic pendoParams = {'visitorId':'someVisitorID', 78 | 'accountId':'someAccountID', 79 | 'vistiorData': {'age':'25', 'country':'USA'}, 80 | 'accountData': {'tier': '1', 'size':'Enterprise'}}; 81 | 82 | // establish connection to server and start a session 83 | await PendoFlutterPlugin.startSession('someAppKey', pendoParams); 84 | ``` 85 | 86 | 3.x: 87 | 88 | ```dart 89 | // establish connection to server 90 | await PendoFlutterPlugin.setup('someAppKey' 91 | null // pendo app params 92 | ); 93 | 94 | // start a session 95 | await PendoFlutterPlugin.startSession('someVisitorID', 96 | 'someAccountID', 97 | {'age': '25', 'country': 'USA'}, 98 | {'tier': '1', 'size': 'Enterprise'}); 99 | ``` 100 | 101 |
initSDKWithoutVisitor 109 | 110 | Call `setup` instead of `initSDKWithoutVisitor`. 111 | 112 | 2.x (deprecated): 113 | 114 | ```dart 115 | // establish connection to server 116 | await PendoFlutterPlugin.initSDKWithoutVisitor('someAppKey' 117 | null // pendo app params 118 | ); 119 | ``` 120 | 121 | 3.x: 122 | 123 | 124 | ```dart 125 | // establish connection to server 126 | await PendoFlutterPlugin.setup('someAppKey' 127 | null // pendo app params 128 | ); 129 | ``` 130 | 131 |
clearVisitor 139 | 140 | Call `startSession` with `null` values instead of `clearVisitor`. 141 | 142 | 2.x (deprecated): 143 | 144 | ```dart 145 | // start a session with an anonymous visitor 146 | await PendoFlutterPlugin.clearVisitor() 147 | ``` 148 | 149 | 3.x: 150 | 151 | ```dart 152 | // start a session with an anonymous visitor 153 | await PendoFlutterPlugin.startSession(null, null, null, null); 154 | ``` 155 | 156 |
switchVisitor 164 | 165 | Call `startSession` with a new visitor or account id instead of `switchVisitor`. 166 | 167 | 2.x (deprecated): 168 | 169 | ```dart 170 | await PendoFlutterPlugin.switchVisitor('someVisitorID', 171 | 'someAccountID', 172 | {'age': '25', 'country': 'USA'}, 173 | {'tier': '1', 'size': 'Enterprise'}); 174 | ``` 175 | 176 | 3.x: 177 | 178 | ```dart 179 | await PendoFlutterPlugin.startSession('someVisitorID', 180 | 'someAccountID', 181 | {'age': '25', 'country': 'USA'}, 182 | {'tier': '1', 'size': 'Enterprise'}); 183 | ``` 184 | 185 |
setAccountId 193 | 194 | Call `startSession` with the new account id value instead of `setAccountId`. 195 | 196 | 2.x (deprecated): 197 | 198 | ```dart 199 | await PendoFlutterPlugin.setAccountId('someAccountID'); 200 | ``` 201 | 202 | 3.x: 203 | 204 | ```dart 205 | // start a new session passing in the new accountId 206 | await PendoFlutterPlugin.startSession('someVisitorID', 207 | 'someAccountID', 208 | {'age': '25', 'country': 'USA'}, 209 | {'tier': '1', 'size': 'Enterprise'}); 210 | ``` 211 | 212 |
-------------------------------------------------------------------------------- /ios/pnddocs/expo_rnn-ios.md: -------------------------------------------------------------------------------- 1 | # Expo iOS using React Native Navigation 2 | 3 | >[!IMPORTANT] 4 | >- **Expo SDK** 41-54 using React Native Navigation 6+ is supported by our codeless solution. 5 | >- **Expo Go** is not supported. Pendo SDK has a native plugin that is not part of the Expo Go app. 6 | Pendo can *only* be used in development builds. For more about development builds read [adding custom native code with development builds](https://docs.expo.dev/workflow/customizing/).
7 | >- Support for React Native's New Architecture (Fabric) is available starting from version 3.7.2. 8 | 9 | >[!IMPORTANT] 10 | >Requirements: 11 | >- Deployment target of `iOS 11` or higher 12 | >- Swift Compatibility `5.7` or higher 13 | >- Xcode `14` or higher 14 | 15 | ## Step 1. Add Pendo dependency 16 | 17 | In the **root folder of your expo app**, add Pendo using one of your package managers: 18 | 19 | ```shell 20 | #example with npx expo 21 | npx expo install rn-pendo-sdk 22 | 23 | #example with npm 24 | npm install --save rn-pendo-sdk 25 | 26 | #example with yarn 27 | yarn add rn-pendo-sdk 28 | ``` 29 | 30 | ## Step 2. Project setup 31 | 32 | >[!NOTE] 33 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 34 | 35 | In the `app.config.js` or `app.json`, add the following: 36 | ```json 37 | { 38 | "plugins": [ 39 | [ 40 | "rn-pendo-sdk", 41 | { 42 | "ios-scheme": "YOUR_IOS_SCHEME_ID", 43 | "android-scheme": "YOUR_ANDROID_SCHEME_ID" 44 | } 45 | ] 46 | ] 47 | } 48 | ``` 49 | This configuration enables pendo to enter pair mode to tag Pages and Features. 50 | 51 | ## Step 3. Production bundle - modify Javascript minification 52 | In the `metro.config.js` file, add the following: 53 | ```typescript 54 | module.exports = { 55 | transformer: { 56 | // ... 57 | minifierConfig: { 58 | keep_classnames: true, // Preserve class names 59 | keep_fnames: true, // Preserve function names 60 | mangle: { 61 | keep_classnames: true, // Preserve class names 62 | keep_fnames: true, // Preserve function names 63 | } 64 | } 65 | } 66 | } 67 | ``` 68 | ## Step 4. Integration 69 | 70 | >[!NOTE] 71 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 72 | 73 | In the application main file (App.js/.ts/.tsx), add the following code: 74 | ```typescript 75 | import { PendoSDK, NavigationLibraryType } from 'rn-pendo-sdk'; 76 | import { Navigation } from "react-native-navigation"; 77 | 78 | function initPendo() { 79 | const navigationOptions = {library: NavigationLibraryType.ReactNativeNavigation, navigation: Navigation}; 80 | const pendoKey = 'YOUR_API_KEY_HERE'; 81 | //note the following API will only setup initial configuration, to start collect analytics use start session 82 | PendoSDK.setup(pendoKey, navigationOptions); 83 | } 84 | 85 | initPendo(); 86 | ``` 87 | Initialize Pendo Session where your visitor is being identified (e.g., login, register, etc.). 88 | ```typescript 89 | const visitorId = 'John Smith'; 90 | const accountId = 'Acme Inc.'; 91 | const visitorData = {'Age': 25, 'Country': 'USA'}; 92 | const accountData = {'Tier': 1, 'Size': 'Enterprise'}; 93 | 94 | PendoSDK.startSession(visitorId, accountId, visitorData, accountData); 95 | ``` 96 | 97 | >[!TIP] 98 | >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). 99 | 100 | ## Step 5. Running the project 101 | To run the project with Pendo integration, you should be able to generate iOS and Android projects. 102 | You can generate them by running `npx expo prebuild`, or `npx expo run:[ios|android]` (which will run prebuild automatically). You can also use development builds in this context - the easiest way to do this is to run `npx expo install expo-dev-client` prior to prebuild or run, and it's also possible to add the library at a later time (additional information can be found here: [Adding custom native code](https://docs.expo.dev/workflow/customizing/#generate-native-projects-with-prebuild)). 103 | 104 | ## Step 6. Verify installation 105 | 106 | 1. In the Pendo UI, go to Settings>Subscription Settings. 107 | 2. Select the **Applications** tab and then your application. 108 | 3. Select the **Install Settings** tab and follow the instructions under Verify Your Installation to ensure you have successfully integrated the Pendo SDK. 109 | 4. Confirm that you can see your app as Integrated under subscription settings. 110 | 111 | ## Limitations 112 | - For the codeless solution to work, all the elements *MUST be wrapped in react-native ui components*.
113 | As with other analytics tools, we are dependent on react-navigation [screen change callbacks](https://reactnavigation.org/docs/screen-tracking/) 114 | which means that codeless tracking analytics is available for screen components only. 115 | 116 | - To support hybrid mode with React Native Navigation, please open a ticket. 117 | 118 | ## Developer documentation 119 | 120 | - API documentation available [here](/api-documentation/rn-apis.md). 121 | 122 | ## Troubleshooting 123 | 124 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 125 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 126 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 127 | -------------------------------------------------------------------------------- /android/pnddocs/expo_rnn-android.md: -------------------------------------------------------------------------------- 1 | # Expo Android using React Native Navigation 2 | 3 | >[!IMPORTANT] 4 | >- **Expo SDK** 41-54 using React Native Navigation 6+ is supported by our codeless solution. 5 | >- **Expo Go** is not supported. Pendo SDK has a native plugin that is not part of the Expo Go app. 6 | Pendo can *only* be used in development builds. For more about development builds read [adding custom native code with development builds](https://docs.expo.dev/workflow/customizing/). 7 | >- Support for React Native's New Architecture (Fabric) is available starting from version 3.7.2. 8 | 9 | 10 | >[!IMPORTANT] 11 | >Requirements: 12 | >- Android Gradle Plugin `8.0` or higher 13 | >- Kotlin version `1.9.0` or higher 14 | >- JAVA version `11` or higher 15 | >- minSdkVersion `21` or higher 16 | >- compileSDKVersion `35` or higher 17 | 18 | ## Step 1. Add Pendo dependency 19 | 20 | In the **root folder of your expo app**, add Pendo using one of your package managers: 21 | 22 | ```shell 23 | #example with npx expo 24 | npx expo install rn-pendo-sdk 25 | 26 | #example with npm 27 | npm install --save rn-pendo-sdk 28 | 29 | #example with yarn 30 | yarn add rn-pendo-sdk 31 | ``` 32 | 33 | ## Step 2. Project setup 34 | 35 | >[!NOTE] 36 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 37 | 38 | In the `app.config.js` or `app.json`, add the following: 39 | ```json 40 | { 41 | "plugins": [ 42 | [ 43 | "rn-pendo-sdk", 44 | { 45 | "ios-scheme": "YOUR_IOS_SCHEME_ID", 46 | "android-scheme": "YOUR_ANDROID_SCHEME_ID" 47 | } 48 | ] 49 | ] 50 | } 51 | ``` 52 | This configuration enables pendo to enter pair mode to tag Pages and Features. 53 | 54 | ## Step 3. Production bundle - modify Javascript minification 55 | 56 | In the `metro.config.js` file, add the following: 57 | ```typescript 58 | module.exports = { 59 | transformer: { 60 | // ... 61 | minifierConfig: { 62 | keep_classnames: true, // Preserve class names 63 | keep_fnames: true, // Preserve function names 64 | mangle: { 65 | keep_classnames: true, // Preserve class names 66 | keep_fnames: true, // Preserve function names 67 | } 68 | } 69 | } 70 | } 71 | ``` 72 | ## Step 4. Integration 73 | 74 | >[!NOTE] 75 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 76 | 77 | In the application main file (App.js/.ts/.tsx), add the following code: 78 | ```typescript 79 | import { PendoSDK, NavigationLibraryType } from 'rn-pendo-sdk'; 80 | import { Navigation } from "react-native-navigation"; 81 | 82 | function initPendo() { 83 | const navigationOptions = {library: NavigationLibraryType.ReactNativeNavigation, navigation: Navigation}; 84 | const pendoKey = 'YOUR_API_KEY_HERE'; 85 | //note the following API will only setup initial configuration, to start collect analytics use start session 86 | PendoSDK.setup(pendoKey, navigationOptions); 87 | } 88 | 89 | initPendo(); 90 | ``` 91 | Initialize Pendo Session where your visitor is being identified (e.g., login, register, etc.). 92 | ```typescript 93 | const visitorId = 'John Smith'; 94 | const accountId = 'Acme Inc.'; 95 | const visitorData = {'Age': 25, 'Country': 'USA'}; 96 | const accountData = {'Tier': 1, 'Size': 'Enterprise'}; 97 | 98 | PendoSDK.startSession(visitorId, accountId, visitorData, accountData); 99 | ``` 100 | 101 | >[!TIP] 102 | >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). 103 | 104 | ## Step 5. Running the project 105 | 106 | To run the project with Pendo integration, you should be able to generate iOS and Android projects. 107 | You can generate them by running `npx expo prebuild`, or `npx expo run:[ios|android]` (which will run prebuild automatically). You can also use development builds in this context - the easiest way to do this is to run `npx expo install expo-dev-client` prior to prebuild or run, and it's also possible to add the library at a later time (additional information can be found here: [Adding custom native code](https://docs.expo.dev/workflow/customizing/#generate-native-projects-with-prebuild)). 108 | 109 | ## Step 6. Verify installation 110 | 111 | 1. In the Pendo UI, go to Settings>Subscription Settings. 112 | 2. Select the **Applications** tab and then your application. 113 | 3. Select the **Install Settings** tab and follow the instructions under Verify Your Installation to ensure you have successfully integrated the Pendo SDK. 114 | 4. Confirm that you can see your app as Integrated under subscription settings. 115 | 116 | ## Limitations 117 | - For the codeless solution to work, all the elements *MUST be wrapped in react-native ui components*.
118 | As with other analytics tools, we are dependent on react-navigation [screen change callbacks](https://reactnavigation.org/docs/screen-tracking/) 119 | which means that codeless tracking analytics is available for screen components only. 120 | - To support hybrid mode with React Native Navigation, please open a ticket. 121 | 122 | ## Developer documentation 123 | 124 | - API documentation available [here](/api-documentation/rn-apis.md). 125 | 126 | ## Troubleshooting 127 | 128 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 129 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 130 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 131 | -------------------------------------------------------------------------------- /android/pnddocs/xamarin_forms-android.md: -------------------------------------------------------------------------------- 1 | # Xamarin Forms Android 2 | 3 | >[!NOTE] 4 | >The following integration instructions are relevant for SDK 3.0 or higher.
Follow our migration instructions to [upgrade from SDK 2.x to 3.0](/migration-docs/README.md) or refer to our [2.x integration instruction](https://github.com/pendo-io/pendo-mobile-sdk/blob/2.22.5/README.md). 5 | 6 | >[!IMPORTANT] 7 | >Requirements: 8 | >- .NET 4 9 | >- Xamarin.Forms version 5.0.0.2612 or higher 10 | >- Kotlin version 1.9.0 or higher 11 | 12 | ## Step 1. Install Pendo SDK 13 | 14 | 1. In **Visual Studio** Solution Explorer, right-click on your shared project, then select "Add" - > "Add NuGet Packages…". 15 | 2. Search for: **pendo-xamarin-forms** with latest version.
16 | 3. Press **Add Package**. 17 | 4. #### Using ProGuard / R8 18 | 19 | - If you are using **ProGuard**, the rules that need to be added to ProGuard can be found here: [pendo-proguard.cfg](/android/pnddocs/pendo-proguard.cfg). 20 | 21 | - 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 your `app/proguard-rules.pro` file. 22 | The optimizations line should look like this: 23 | `-optimizations *other optimizations*,!code/allocation/variable` 24 | 25 | 26 | ## Step 2. Integrate with the Pendo SDK 27 | 28 | >[!NOTE] 29 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 30 | 31 | 1. #### Open the shared project **App.xaml.cs** 32 | 33 | Add the following under 'using': 34 | 35 | ```c# 36 | using PendoSDKXamarin; 37 | 38 | namespace ExampleApp 39 | { 40 | public partial class App : Application 41 | { 42 | private static IPendoInterface pendo = DependencyService.Get(); 43 | 44 | ... 45 | 46 | } 47 | } 48 | ``` 49 | 50 | In the **protected override void OnStart()** method, add the following code: 51 | 52 | ```c# 53 | protected override void OnStart() 54 | { 55 | string apiKey = "YOUR_API_KEY_HERE"; 56 | pendo.Setup(apiKey); 57 | 58 | ... 59 | } 60 | ``` 61 | 62 | 2. #### Start the visitor's session in the Page where your visitor is being identified (e.g., login, register, etc.). 63 | 64 | ```c# 65 | using PendoSDKXamarin; 66 | 67 | namespace ExampleApp 68 | { 69 | class ExampleLoginClass 70 | { 71 | ... 72 | private static IPendoInterface Pendo = DependencyService.Get(); 73 | 74 | public void MethodExample() 75 | { 76 | 77 | ... 78 | 79 | var visitorId = "VISITOR-UNIQUE-ID"; 80 | var accountId = "ACCOUNT-UNIQUE-ID"; 81 | 82 | var visitorData = new Dictionary 83 | { 84 | { "age", 27 }, 85 | { "country", "USA" } 86 | }; 87 | 88 | var accountData = new Dictionary 89 | { 90 | { "Tier", 1 }, 91 | { "Size", "Enterprise" } 92 | }; 93 | 94 | pendo.StartSession(visitorId, accountId, visitorData, accountData); 95 | 96 | ... 97 | } 98 | 99 | ... 100 | 101 | } 102 | ``` 103 | 104 | **visitorId**: a user identifier (e.g., John Smith) 105 | **visitorData**: the user metadata (e.g., email, phone, country, etc.) 106 | **accountId**: an affiliation of the user to a specific company or group (e.g., Acme inc.) 107 | **accountData** : the account metadata (e.g., tier, level, ARR, etc.) 108 | 109 | This code ends the previous mobile session (if applicable), starts a new mobile session, and retrieves all guides based on the provided information. 110 | 111 | >[!TIP] 112 | >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). 113 | 114 | ## Step 3. Connect mobile device for tagging and testing 115 | 116 | >[!NOTE] 117 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 118 | 119 | This step enables Page tagging 120 | and guide testing capabilities. 121 | 122 | Add the following **activity** to the application **AndroidManifest.xml** in the `` tag: 123 | 124 | ```xml 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | ``` 134 | 135 | ## Step 4. Verify installation 136 | 137 | 1. Test using Visual Studio: 138 | Run the app. 139 | Review the Android Studio logcat and look for the following message: 140 | `Pendo SDK was successfully integrated and connected to the server.` 141 | 2. In the Pendo UI, go to `Settings` > `Subscription Settings`. 142 | 3. Select your application from the list. 143 | 4. Select the `Install Settings tab` and follow the instructions under `Verify Your Installation` to ensure you have successfully integrated the Pendo SDK. 144 | 5. Confirm that you can see your app as `Integrated` under subscription settings. 145 | 146 | ------------- 147 | 148 | ## Developer documentation 149 | 150 | - API documentation available [here](/api-documentation/xamarin-forms-apis.md). 151 | 152 | ## Troubleshooting 153 | 154 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 155 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 156 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 157 | -------------------------------------------------------------------------------- /ios/pnddocs/xamarin_forms-ios.md: -------------------------------------------------------------------------------- 1 | # Xamarin Forms iOS 2 | 3 | 4 | >[!NOTE] 5 | >The following integration instructions are relevant for SDK 3.0 or higher.
Follow our migration instructions to [upgrade from SDK 2.x to 3.0](/migration-docs/README.md) or refer to our [2.x integration instruction](https://github.com/pendo-io/pendo-mobile-sdk/blob/2.22.5/README.md). 6 | 7 | >[!IMPORTANT] 8 | > Requirements: 9 | > - .NET 4 10 | > - Xamarin.Forms version 5.0.0.2612 or higher 11 | 12 | ## Step 1. Install Pendo SDK 13 | 14 | 1. In **Visual Studio** Solution Explorer, right-click on your shared project, then select "Add" - > "Add NuGet Packages…". 15 | 2. Search for: **pendo-xamarin-forms** with latest version.
16 | 3. Press **Add Package**. 17 | 18 | ## Step 2. Integrate with the Pendo SDK 19 | 20 | >[!NOTE] 21 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 22 | 23 | 1. Open the shared project **App.xaml.cs**: 24 | 25 | Add the following code: 26 | 27 | ```c# 28 | using PendoSDKXamarin; 29 | 30 | namespace ExampleApp 31 | { 32 | public partial class App : Application 33 | { 34 | private static IPendoInterface pendo = DependencyService.Get(); 35 | 36 | ... 37 | 38 | } 39 | 40 | ... 41 | ``` 42 | 43 | In the **protected override void OnStart()** method, add the following code: 44 | 45 | ```c# 46 | protected override void OnStart() 47 | { 48 | string apiKey = "YOUR_API_KEY_HERE"; 49 | pendo.Setup(apiKey); 50 | 51 | ... 52 | 53 | } 54 | ``` 55 | 56 | 2. Start the visitor's session in the Page where your visitor is being identified (e.g., login, register, etc.). 57 | 58 | ```c# 59 | using PendoSDKXamarin; 60 | 61 | namespace ExampleApp 62 | { 63 | 64 | class ExampleLoginClass 65 | { 66 | private static IPendoInterface pendo = DependencyService.Get(); 67 | 68 | public void ExampleMethod() 69 | { 70 | ... 71 | 72 | var visitorId = "VISITOR-UNIQUE-ID"; 73 | var accountId = "ACCOUNT-UNIQUE-ID"; 74 | 75 | var visitorData = new Dictionary 76 | { 77 | { "age", 27 }, 78 | { "country", "USA" } 79 | }; 80 | 81 | var accountData = new Dictionary 82 | { 83 | { "Tier", 1 }, 84 | { "Size", "Enterprise" } 85 | }; 86 | 87 | pendo.StartSession(visitorId, accountId, visitorData, accountData); 88 | 89 | ... 90 | 91 | } 92 | 93 | ... 94 | 95 | } 96 | } 97 | ``` 98 | 99 | **visitorId**: a user identifier (e.g., John Smith) 100 | **visitorData**: the user metadata (e.g., email, phone, country, etc.) 101 | **accountId**: an affiliation of the user to a specific company or group (e.g., Acme inc.) 102 | **accountData** : the account metadata (e.g., tier, level, ARR, etc.) 103 | 104 | This code ends the previous mobile session (if applicable), starts a new mobile session, and retrieves all guides based on the provided information. 105 | 106 | >[!TIP] 107 | >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). 108 | 109 | 110 | ## Step 3. Connect mobile device for tagging and testing 111 | 112 | >[!NOTE] 113 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 114 | 115 | These steps enable page tagging 116 | and guide testing capabilities. 117 | 118 | 1. Add a Pendo URL scheme to the **info.plist** file: 119 | 120 | Screenshot 2023-12-05 at 22 01 30 121 | 122 | Under the iOS App Target > open info.plist > if `URL Types` doesn't exist, click on 'Add new entry' of type `Array` and name it `URL types`. Create a new `Dictionary` inside the `Array` with two entries: 123 | - `URL identifier` of type `String` with a value that begins with `pendo` (ex. `pendo-scheme-d`). 124 | - `URL Schemes` of type `Array`. Add a `String` item with `YOUR_SCHEME_ID` as the value. 125 | 126 | 2. Add or modify the function **OpenURL**: 127 | 128 | Open ***AppDelegate.cs*** file and the following code: 129 | 130 | ```C# 131 | using PendoForms; 132 | 133 | ... 134 | 135 | public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options) 136 | { 137 | if (url.Scheme.Contains("pendo")) 138 | { 139 | PendoManager.InitWithUrl(url.AbsoluteString); 140 | 141 | return true; 142 | } 143 | return base.OpenUrl(app, url, options); 144 | } 145 | ``` 146 | 147 | ## Step 4. Verify installation 148 | 149 | 1. Test using Visual Studio: 150 | Run the app. 151 | Review the Xcode console and look for the following message: 152 | `Pendo SDK was successfully integrated and connected to the server.` 153 | 2. In the Pendo UI, go to `Settings` > `Subscription Settings`. 154 | 3. Select your application from the list. 155 | 4. Select the `Install Settings tab` and follow the instructions under `Verify Your Installation` to ensure you have successfully integrated the Pendo SDK. 156 | 5. Confirm that you can see your app as `Integrated` under subscription settings. 157 | 158 | 159 | ## Developer documentation 160 | 161 | - API documentation available [here](/api-documentation/xamarin-forms-apis.md). 162 | 163 | ## Troubleshooting 164 | 165 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 166 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 167 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 168 | -------------------------------------------------------------------------------- /ios/pnddocs/expo_rn-ios.md: -------------------------------------------------------------------------------- 1 | # Expo iOS using React Navigation 2 | 3 | >[!IMPORTANT] 4 | >- **Expo SDK** 41-54 using React Navigation 5+ is supported by our codeless solution. 5 | >- **Expo Go** is not supported. Pendo SDK has a native plugin that is not part of the Expo Go app. 6 | Pendo can *only* be used in development builds. For more about development builds read [adding custom native code with development builds](https://docs.expo.dev/workflow/customizing/). 7 | >- Support for React Native's New Architecture (Fabric) is available starting from version 3.7.2. 8 | 9 | >[!IMPORTANT] 10 | >Requirements: 11 | >- Deployment target of `iOS 11` or higher 12 | >- Swift Compatibility `5.7` or higher 13 | >- Xcode `14` or higher 14 | 15 | ## Step 1. Add Pendo dependency 16 | 17 | In the **root folder of your expo app**, add Pendo using one of your package managers: 18 | 19 | ```shell 20 | #example with npx expo 21 | npx expo install rn-pendo-sdk 22 | 23 | #example with npm 24 | npm install --save rn-pendo-sdk 25 | 26 | #example with yarn 27 | yarn add rn-pendo-sdk 28 | ``` 29 | 30 | ## Step 2. Project setup 31 | 32 | >[!NOTE] 33 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 34 | 35 | In the `app.config.js` or `app.json`, add the following: 36 | ```json 37 | { 38 | "plugins": [ 39 | [ 40 | "rn-pendo-sdk", 41 | { 42 | "ios-scheme": "YOUR_IOS_SCHEME_ID", 43 | "android-scheme": "YOUR_ANDROID_SCHEME_ID" 44 | } 45 | ] 46 | ] 47 | } 48 | ``` 49 | This configuration enables Pendo to enter pair mode to tag Pages and Features. 50 | 51 | ## Step 3. Production bundle - modify Javascript minification 52 | In the `metro.config.js` file, add the following: 53 | ```javascript 54 | module.exports = { 55 | transformer: { 56 | // ... 57 | minifierConfig: { 58 | keep_classnames: true, // Preserve class names 59 | keep_fnames: true, // Preserve function names 60 | mangle: { 61 | keep_classnames: true, // Preserve class names 62 | keep_fnames: true, // Preserve function names 63 | } 64 | } 65 | } 66 | } 67 | ``` 68 | ## Step 4.Integration 69 | 70 | >[!NOTE] 71 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 72 | 73 | In the application main file (App.js/.ts/.tsx), add the following code: 74 | 75 | ```typescript 76 | import {PendoSDK, NavigationLibraryType} from "rn-pendo-sdk"; 77 | 78 | function initPendo() { 79 | const navigationOptions = {'library': NavigationLibraryType.ReactNavigation}; 80 | const key = 'YOUR_API_KEY_HERE'; 81 | //note the following API will only setup initial configuration, to start collect analytics use start session 82 | PendoSDK.setup(key, navigationOptions); 83 | } 84 | 85 | initPendo(); 86 | ``` 87 | 88 | In the file where the `NavigationContainer` is created: 89 | import `WithPendoReactNavigation`: 90 | 91 | ```typescript 92 | import {WithPendoReactNavigation} from 'rn-pendo-sdk' 93 | ``` 94 | 95 | Wrap `NavigationContainer` with `WithPendoReactNavigation` HOC: 96 | 97 | ```typescript 98 | const PendoNavigationContainer = WithPendoReactNavigation(NavigationContainer); 99 | ``` 100 | 101 | Replace `NavigationContainer` tag with `PendoNavigationContainer` tag: 102 | 103 | ```typescript 104 | 105 | {/* Rest of your app code */} 106 | 107 | ``` 108 | Initialize Pendo Session where your visitor is being identified (e.g., login, register, etc.). 109 | ```typescript 110 | const visitorId = 'John Smith'; 111 | const accountId = 'Acme Inc.'; 112 | const visitorData = {'Age': 25, 'Country': 'USA'}; 113 | const accountData = {'Tier': 1, 'Size': 'Enterprise'}; 114 | 115 | PendoSDK.startSession(visitorId, accountId, visitorData, accountData); 116 | ``` 117 | 118 | >[!TIP] 119 | >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). 120 | 121 | If some of your own _custom_ react native components are not taggable because we can't detect it in the regular detection flow, 122 | you can try to add it manually to the scanning flow. To do this, add a prop `nativeID` to your component. 123 | For instance: 124 | ```typescript 125 | 126 | 127 | ``` 128 | and change your integration to the following: 129 | ```typescript 130 | const PendoNavigationContainer = WithPendoReactNavigation(NavigationContainer,{nativeIDs:["myProp"]}); 131 | ``` 132 | ## Step 5. Running the project 133 | To run the project with Pendo integration, you should be able to generate iOS and Android projects. 134 | You can generate them by running `npx expo prebuild`, or `npx expo run:[ios|android]` (which will run prebuild automatically). You can also use development builds in this context - the easiest way to do this is to run `npx expo install expo-dev-client` prior to prebuild or run, and it's also possible to add the library at any later time (additional information can be found here: [Adding custom native code](https://docs.expo.dev/workflow/customizing/#generate-native-projects-with-prebuild)). 135 | 136 | ## Step 6. Verify installation 137 | 138 | 1. In the Pendo UI, go to Settings>Subscription Settings. 139 | 2. Select the **Applications** tab and then your application. 140 | 3. Select the **Install Settings** tab and follow the instructions under Verify Your Installation to ensure you have successfully integrated the Pendo SDK. 141 | 4. Confirm that you can see your app as Integrated under subscription settings. 142 | 143 | 144 | ## Limitations 145 | For the codeless solution to work, all the elements *MUST be wrapped in react-native ui components*.
146 | As with other analytics tools, we are dependent on react-navigation [screen change callbacks](https://reactnavigation.org/docs/screen-tracking/) 147 | which means that codeless tracking analytics is available for screen components only. 148 | 149 | ## Developer documentation 150 | 151 | - API documentation available [here](/api-documentation/rn-apis.md). 152 | 153 | ## Troubleshooting 154 | 155 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 156 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 157 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 158 | -------------------------------------------------------------------------------- /android/pnddocs/expo_rn-android.md: -------------------------------------------------------------------------------- 1 | # Expo Android using React Navigation 2 | 3 | >[!IMPORTANT] 4 | >- **Expo SDK** 41-54 using React Navigation 5+ is supported by our codeless solution. 5 | >- **Expo Go** is not supported. Pendo SDK has a native plugin that is not part of the Expo Go app. 6 | Pendo can *only* be used in development builds. For more about development builds read [adding custom native code with development builds](https://docs.expo.dev/workflow/customizing/). 7 | >- Support for React Native's New Architecture (Fabric) is available starting from version 3.7.2. 8 | 9 | 10 | >[!IMPORTANT] 11 | >Requirements: 12 | >- Android Gradle Plugin `8.0` or higher 13 | >- Kotlin version `1.9.0` or higher 14 | >- JAVA version `11` or higher 15 | >- minSdkVersion `21` or higher 16 | >- compileSDKVersion `35` or higher 17 | 18 | ## Step 1. Add Pendo dependency 19 | 20 | In the **root folder of your expo app**, add Pendo using one of your package managers: 21 | 22 | ```shell 23 | #example with npx expo 24 | npx expo install rn-pendo-sdk 25 | 26 | #example with npm 27 | npm install --save rn-pendo-sdk 28 | 29 | #example with yarn 30 | yarn add rn-pendo-sdk 31 | ``` 32 | 33 | ## Step 2. Project setup 34 | 35 | >[!NOTE] 36 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 37 | 38 | In the `app.config.js` or `app.json`, add the following: 39 | ```json 40 | { 41 | "plugins": [ 42 | [ 43 | "rn-pendo-sdk", 44 | { 45 | "ios-scheme": "YOUR_IOS_SCHEME_ID", 46 | "android-scheme": "YOUR_ANDROID_SCHEME_ID" 47 | } 48 | ] 49 | ] 50 | } 51 | ``` 52 | This configuration enables Pendo to enter pair mode to tag Pages and Features. 53 | 54 | ## Step 3. Production bundle - modify Javascript minification 55 | In the `metro.config.js` file, add the following: 56 | ```javascript 57 | module.exports = { 58 | transformer: { 59 | // ... 60 | minifierConfig: { 61 | keep_classnames: true, // Preserve class names 62 | keep_fnames: true, // Preserve function names 63 | mangle: { 64 | keep_classnames: true, // Preserve class names 65 | keep_fnames: true, // Preserve function names 66 | } 67 | } 68 | } 69 | } 70 | ``` 71 | ## Step 4. Integration 72 | 73 | >[!NOTE] 74 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 75 | 76 | In the application main file (App.js/.ts/.tsx), add the following code: 77 | 78 | ```typescript 79 | import {PendoSDK, NavigationLibraryType} from "rn-pendo-sdk"; 80 | 81 | function initPendo() { 82 | const navigationOptions = { 'library': NavigationLibraryType.ReactNavigation }; 83 | const key = 'YOUR_API_KEY_HERE'; 84 | //note the following API will only setup initial configuration, to start collect analytics use start session 85 | PendoSDK.setup(key, navigationOptions); 86 | } 87 | 88 | initPendo(); 89 | ``` 90 | 91 | In the file where the `NavigationContainer` is created: 92 | import `WithPendoReactNavigation`: 93 | 94 | ```typescript 95 | import {WithPendoReactNavigation} from 'rn-pendo-sdk' 96 | ``` 97 | 98 | Wrap `NavigationContainer` with `WithPendoReactNavigation` HOC: 99 | 100 | ```typescript 101 | const PendoNavigationContainer = WithPendoReactNavigation(NavigationContainer); 102 | ``` 103 | 104 | replace `NavigationContainer` tag with `PendoNavigationContainer` tag: 105 | 106 | ```typescript 107 | 108 | {/* Rest of your app code */} 109 | 110 | ``` 111 | Initialize Pendo Session where your visitor is being identified (e.g., login, register, etc.). 112 | ```typescript 113 | const visitorId = 'John Smith'; 114 | const accountId = 'Acme Inc.'; 115 | const visitorData = {'Age': 25, 'Country': 'USA'}; 116 | const accountData = {'Tier': 1, 'Size': 'Enterprise'}; 117 | 118 | PendoSDK.startSession(visitorId, accountId, visitorData, accountData); 119 | ``` 120 | 121 | >[!TIP] 122 | >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). 123 | 124 | If some of your own _custom_ react native components are not taggable because we can't detect it in the regular detection flow, 125 | you can try to add it manually to the scanning flow. To do this, add a prop `nativeID` to your component. 126 | For instance: 127 | ```typescript 128 | 129 | 130 | ``` 131 | and change your integration to the following: 132 | ```typescript 133 | const PendoNavigationContainer = WithPendoReactNavigation(NavigationContainer,{nativeIDs:["myProp"]}); 134 | ``` 135 | ## Step 5. Running the project 136 | To run the project with Pendo integration, you should be able to generate iOS and Android projects. 137 | You can generate them by running `npx expo prebuild`, or `npx expo run:[ios|android]` (which will run prebuild automatically). You can also use development builds in this context - the easiest way to do this is to run `npx expo install expo-dev-client` prior to prebuild or run, and it's also possible to add the library at any later time (additional information can be found here: [Adding custom native code](https://docs.expo.dev/workflow/customizing/#generate-native-projects-with-prebuild)). 138 | 139 | ## Step 6. Verify installation 140 | 141 | 1. In the Pendo UI, go to Settings>Subscription Settings. 142 | 2. Select the **Applications** tab and then your application. 143 | 3. Select the **Install Settings** tab and follow the instructions under Verify Your Installation to ensure you have successfully integrated the Pendo SDK. 144 | 4. Confirm that you can see your app as Integrated under subscription settings. 145 | 146 | ## Limitations 147 | For the codeless solution to work, all the elements *MUST be wrapped in react-native ui components*.
148 | As with other analytics tools, we are dependent on react-navigation [screen change callbacks](https://reactnavigation.org/docs/screen-tracking/) 149 | which means that codeless tracking analytics is available for screen components only. 150 | 151 | ## Developer documentation 152 | 153 | - API documentation available [here](/api-documentation/rn-apis.md). 154 | 155 | ## Troubleshooting 156 | 157 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 158 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 159 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 160 | -------------------------------------------------------------------------------- /ios/pnddocs/expo_router-ios.md: -------------------------------------------------------------------------------- 1 | # Expo iOS using Expo Router (**Beta**) 2 | 3 | >[!IMPORTANT] 4 | >- **Expo SDK** 41-54 using React Navigation 5+ is supported by our codeless solution. 5 | >- **Expo Go** is not supported. Pendo SDK has a native plugin that is not part of the Expo Go app. 6 | Pendo can *only* be used in development builds. For more about development builds read [adding custom native code with development builds](https://docs.expo.dev/workflow/customizing/). 7 | >- Support for React Native's New Architecture (Fabric) is available starting from version 3.7.2. 8 | 9 | >[!IMPORTANT] 10 | >Requirements: 11 | >- Deployment target of `iOS 11` or higher 12 | >- Swift Compatibility `5.7` or higher 13 | >- Xcode `14` or higher 14 | 15 | ## Step 1. Add Pendo dependency 16 | 17 | In the **root folder of your expo app**, add Pendo using one of your package managers: 18 | 19 | ```shell 20 | #example with npx expo 21 | npx expo install rn-pendo-sdk 22 | 23 | #example with npm 24 | npm install --save rn-pendo-sdk 25 | 26 | #example with yarn 27 | yarn add rn-pendo-sdk 28 | ``` 29 | 30 | ## Step 2. Project setup 31 | 32 | >[!NOTE] 33 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 34 | 35 | In the `app.config.js` or `app.json`, add the following: 36 | ```json 37 | { 38 | "plugins": [ 39 | [ 40 | "rn-pendo-sdk", 41 | { 42 | "ios-scheme": "YOUR_IOS_SCHEME_ID", 43 | "android-scheme": "YOUR_ANDROID_SCHEME_ID" 44 | } 45 | ] 46 | ] 47 | } 48 | ``` 49 | This configuration enables Pendo to enter pair mode to tag Pages and Features. 50 | 51 | ## Step 3. Production bundle - modify Javascript minification 52 | In the `metro.config.js` file, add the following: 53 | ```javascript 54 | module.exports = { 55 | transformer: { 56 | // ... 57 | minifierConfig: { 58 | keep_classnames: true, // Preserve class names 59 | keep_fnames: true, // Preserve function names 60 | mangle: { 61 | keep_classnames: true, // Preserve class names 62 | keep_fnames: true, // Preserve function names 63 | } 64 | } 65 | } 66 | } 67 | ``` 68 | ## Step 4.Integration 69 | 70 | >[!NOTE] 71 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 72 | 73 | In the application main file (App.js/.ts/.tsx), add the following code: 74 | 75 | ```typescript 76 | import {PendoSDK, NavigationLibraryType} from "rn-pendo-sdk"; 77 | 78 | function initPendo() { 79 | const navigationOptions = {'library': NavigationLibraryType.ExpoRouter}; 80 | const key = 'YOUR_API_KEY_HERE'; 81 | //note the following API will only setup initial configuration, to start collect analytics use start session 82 | PendoSDK.setup(key, navigationOptions); 83 | } 84 | 85 | initPendo(); 86 | ``` 87 | In the file where your **Root Layout** is created 88 | import `WithPendoExpoRouter`, `usePathname` and `useGlobalSearchParams`: 89 | 90 | ```typescript 91 | import {WithPendoExpoRouter} from 'rn-pendo-sdk' 92 | import {useGlobalSearchParams, usePathname} from 'expo-router'; 93 | ``` 94 | 95 | Add the following code to the method building your **Root Layout** component. Make sure to pass **props** to your Root Layout method. 96 | 97 | ```typescript 98 | function RootLayout(props: any): ReactNode { 99 | ... 100 | let pathname = usePathname(); 101 | const params = useGlobalSearchParams(); 102 | 103 | useEffect(() => { 104 | props.onExpoRouterStateChange(pathname, params); 105 | }, [pathname, params, props]); 106 | ... 107 | } 108 | ``` 109 | Wrap your **Root Layout** component with **WithPendoExpoRouter**: 110 | ```typescript 111 | export default WithPendoExpoRouter(RootLayout); 112 | ``` 113 | Initialize Pendo Session where your visitor is being identified (e.g., login, register, etc.). 114 | ```typescript 115 | const visitorId = 'John Smith'; 116 | const accountId = 'Acme Inc.'; 117 | const visitorData = {'Age': 25, 'Country': 'USA'}; 118 | const accountData = {'Tier': 1, 'Size': 'Enterprise'}; 119 | 120 | PendoSDK.startSession(visitorId, accountId, visitorData, accountData); 121 | ``` 122 | 123 | >[!TIP] 124 | >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). 125 | 126 | If some of your own _custom_ react native components are not taggable because we can't detect it in the regular detection flow, 127 | you can try to add it manually to the scanning flow. To do this, add a prop `nativeID` to your component. 128 | For instance: 129 | ```typescript 130 | 131 | 132 | ``` 133 | and change your integration to the following: 134 | ```typescript 135 | export default WithPendoExpoRouter(RootLayout, {nativeIDs:["myProp"]}); 136 | ``` 137 | ## Step 5. Running the project 138 | To run the project with Pendo integration, you should be able to generate iOS and Android projects. 139 | You can generate them by running `npx expo prebuild`, or `npx expo run:[ios|android]` (which will run prebuild automatically). You can also use development builds in this context - the easiest way to do this is to run `npx expo install expo-dev-client` prior to prebuild or run, and it's also possible to add the library at any later time (additional information can be found here: [Adding custom native code](https://docs.expo.dev/workflow/customizing/#generate-native-projects-with-prebuild)). 140 | 141 | ## Step 6. Verify installation 142 | 143 | 1. In the Pendo UI, go to Settings>Subscription Settings. 144 | 2. Select the **Applications** tab and then your application. 145 | 3. Select the **Install Settings** tab and follow the instructions under Verify Your Installation to ensure you have successfully integrated the Pendo SDK. 146 | 4. Confirm that you can see your app as Integrated under subscription settings. 147 | 148 | 149 | ## Limitations 150 | For the codeless solution to work, all the elements *MUST be wrapped in react-native ui components*.
151 | As with other analytics tools, we are dependent on react-navigation [screen change callbacks](https://reactnavigation.org/docs/screen-tracking/) 152 | which means that codeless tracking analytics is available for screen components only. 153 | 154 | ## Developer documentation 155 | 156 | - API documentation available [here](/api-documentation/rn-apis.md). 157 | 158 | ## Troubleshooting 159 | 160 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 161 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 162 | - For additional documentation, visit our [Help Center Mobile Section](https://support.pendo.io/hc/en-us/categories/4403654621851-Mobile). 163 | -------------------------------------------------------------------------------- /android/pnddocs/expo_router-android.md: -------------------------------------------------------------------------------- 1 | # Expo Android using Expo Router (**Beta**) 2 | 3 | >[!IMPORTANT] 4 | >- **Expo SDK** 41-54 using React Navigation 5+ is supported by our codeless solution. 5 | >- **Expo Go** is not supported. Pendo SDK has a native plugin that is not part of the Expo Go app. 6 | Pendo can *only* be used in development builds. For more about development builds read [adding custom native code with development builds](https://docs.expo.dev/workflow/customizing/). 7 | >- Support for React Native's New Architecture (Fabric) is available starting from version 3.7.2. 8 | 9 | >[!IMPORTANT] 10 | >Requirements: 11 | >- Android Gradle Plugin `8.0` or higher 12 | >- Kotlin version `1.9.0` or higher 13 | >- JAVA version `11` or higher 14 | >- minSdkVersion `21` or higher 15 | >- compileSDKVersion `35` or higher 16 | 17 | ## Step 1. Add Pendo dependency 18 | 19 | In the **root folder of your expo app**, add Pendo using one of your package managers: 20 | 21 | ```shell 22 | #example with npx expo 23 | npx expo install rn-pendo-sdk 24 | 25 | #example with npm 26 | npm install --save rn-pendo-sdk 27 | 28 | #example with yarn 29 | yarn add rn-pendo-sdk 30 | ``` 31 | 32 | ## Step 2. Project setup 33 | 34 | >[!NOTE] 35 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 36 | 37 | In the `app.config.js` or `app.json`, add the following: 38 | ```json 39 | { 40 | "plugins": [ 41 | [ 42 | "rn-pendo-sdk", 43 | { 44 | "ios-scheme": "YOUR_IOS_SCHEME_ID", 45 | "android-scheme": "YOUR_ANDROID_SCHEME_ID" 46 | } 47 | ] 48 | ] 49 | } 50 | ``` 51 | This configuration enables Pendo to enter pair mode to tag Pages and Features. 52 | 53 | ## Step 3. Production bundle - modify Javascript minification 54 | In the `metro.config.js` file, add the following: 55 | ```javascript 56 | module.exports = { 57 | transformer: { 58 | // ... 59 | minifierConfig: { 60 | keep_classnames: true, // Preserve class names 61 | keep_fnames: true, // Preserve function names 62 | mangle: { 63 | keep_classnames: true, // Preserve class names 64 | keep_fnames: true, // Preserve function names 65 | } 66 | } 67 | } 68 | } 69 | ``` 70 | ## Step 4. Integration 71 | 72 | >[!NOTE] 73 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 74 | 75 | In the application main file (App.js/.ts/.tsx), add the following code: 76 | 77 | ```typescript 78 | import {PendoSDK, NavigationLibraryType} from "rn-pendo-sdk"; 79 | 80 | function initPendo() { 81 | const navigationOptions = {'library': NavigationLibraryType.ExpoRouter}; 82 | const key = 'YOUR_API_KEY_HERE'; 83 | //note the following API will only setup initial configuration, to start collect analytics use start session 84 | PendoSDK.setup(key, navigationOptions); 85 | } 86 | 87 | initPendo(); 88 | ``` 89 | 90 | In the file where your Root Layout is created 91 | import `WithPendoExpoRouter`, `usePathname` and `useGlobalSearchParams`: 92 | 93 | ```typescript 94 | import {WithPendoExpoRouter} from 'rn-pendo-sdk' 95 | import {useGlobalSearchParams, usePathname} from 'expo-router'; 96 | ``` 97 | 98 | Add the following code to your Root Layout component. Make sure to pass props to your Root Layout component. 99 | 100 | ```typescript 101 | function RootLayout(props: any): ReactNode { 102 | ... 103 | let pathname = usePathname(); 104 | const params = useGlobalSearchParams(); 105 | 106 | useEffect(() => { 107 | props.onExpoRouterStateChange(pathname, params); 108 | }, [pathname, params, props]); 109 | ... 110 | } 111 | ``` 112 | Wrap your Root Layout component with WithPendoExpoRouter: 113 | ```typescript 114 | export default WithPendoExpoRouter(RootLayout); 115 | ``` 116 | Initialize Pendo Session where your visitor is being identified (e.g., login, register, etc.). 117 | ```typescript 118 | const visitorId = 'John Smith'; 119 | const accountId = 'Acme Inc.'; 120 | const visitorData = {'Age': 25, 'Country': 'USA'}; 121 | const accountData = {'Tier': 1, 'Size': 'Enterprise'}; 122 | 123 | PendoSDK.startSession(visitorId, accountId, visitorData, accountData); 124 | ``` 125 | 126 | >[!TIP] 127 | >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). 128 | 129 | If some of your own _custom_ react native components are not taggable because we can't detect it in the regular detection flow, 130 | you can try to add it manually to the scanning flow. To do this, add a prop `nativeID` to your component. 131 | For instance: 132 | ```typescript 133 | 134 | 135 | ``` 136 | and change your integration to the following: 137 | ```typescript 138 | const PendoNavigationContainer = WithPendoReactNavigation(NavigationContainer,{nativeIDs:["myProp"]}); 139 | ``` 140 | ## Step 5. Running the project 141 | To run the project with Pendo integration, you should be able to generate iOS and Android projects. 142 | You can generate them by running `npx expo prebuild`, or `npx expo run:[ios|android]` (which will run prebuild automatically). You can also use development builds in this context - the easiest way to do this is to run `npx expo install expo-dev-client` prior to prebuild or run, and it's also possible to add the library at any later time (additional information can be found here: [Adding custom native code](https://docs.expo.dev/workflow/customizing/#generate-native-projects-with-prebuild)). 143 | 144 | ## Step 6. Verify installation 145 | 146 | 1. In the Pendo UI, go to Settings>Subscription Settings. 147 | 2. Select the **Applications** tab and then your application. 148 | 3. Select the **Install Settings** tab and follow the instructions under Verify Your Installation to ensure you have successfully integrated the Pendo SDK. 149 | 4. Confirm that you can see your app as Integrated under subscription settings. 150 | 151 | ## Limitations 152 | For the codeless solution to work, all the elements *MUST be wrapped in react-native ui components*.
153 | As with other analytics tools, we are dependent on react-navigation [screen change callbacks](https://reactnavigation.org/docs/screen-tracking/) 154 | which means that codeless tracking analytics is available for screen components only. 155 | 156 | ## Developer documentation 157 | 158 | - API documentation available [here](/api-documentation/rn-apis.md). 159 | 160 | ## Troubleshooting 161 | 162 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 163 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 164 | - For additional documentation, visit our [Help Center Mobile Section](https://support.pendo.io/hc/en-us/categories/4403654621851-Mobile). 165 | -------------------------------------------------------------------------------- /migration-docs/react-native-2.x-to-3.x-migration.md: -------------------------------------------------------------------------------- 1 | # React Native migration from version 2.x to version 3.x 2 | 3 | 4 | Follow these instructions to resolve breaking changes in your app: 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 253 | 254 |
Component / API Instructions
withPendoRN 18 | 19 | Use `WithPendoReactNavigation` instead of `withPendoRN` and remove any Pendo related code (ref, onStateChange and onReady implementations): 20 | 21 | 2.x (deprecated): 22 | 23 | ```javascript 24 | // in the file where the NavigationContainer is created 25 | import {withPendoRN} from 'rn-pendo-sdk' 26 | 27 | function RootNavigator(props) { 28 | const navigationRef = useRef(); 29 | return ( 30 | { 33 | const state = navigationRef.current.getRootState() 34 | props.onStateChange(state); 35 | }} 36 | onReady ={()=>{ 37 | const state = navigationRef.current.getRootState() 38 | props.onStateChange(state); 39 | }}> 40 | {MainStackScreen()} 41 | 42 | ) 43 | export default withPendoRN(RootNavigator); 44 | } 45 | ``` 46 | 47 | 3.x: 48 | 49 | ```javascript 50 | // in the file where the NavigationContainer is created 51 | import {WithPendoReactNavigation} from 'rn-pendo-sdk' 52 | 53 | // wrap NavigationContainer with WithPendoReactNavigation HOC 54 | const PendoNavigationContainer = WithPendoReactNavigation(NavigationContainer); 55 | 56 | // replace NavigationContainer tag with PendoNavigationContainer tag 57 | 58 | 59 | {/* The rest of your app code */} 60 | 61 | 62 | ``` 63 | 64 |
initSDK 72 | 73 | Replace `initSDK` by calling `setup` and then `startSession`. 74 | 75 | 2.x (deprecated): 76 | 77 | ```javascript 78 | import { PendoSDK, NavigationLibraryType } from 'rn-pendo-sdk'; 79 | 80 | // only if using React Native Navigation 81 | import { Navigation } from "react-native-navigation"; 82 | 83 | // set session parameters 84 | const pendoParams = {'visitorId': 'someVisitorID', 85 | 'accountId': 'someAccountID', 86 | 'vistiorData': {'age': '25', 'country': 'USA'}, 87 | 'accountData': {'tier': '1', 'size': 'Enterprise'}}; 88 | 89 | // select the correct NavigationLibraryType according to your application 90 | const navigationOptions = {library: NavigationLibraryType.ReactNavigation}; 91 | const navigationOptions = {library: NavigationLibraryType.ReactNativeNavigation, navigation: Navigation}; 92 | const navigationOptions = {library: NavigationLibraryType.Other}; 93 | 94 | // establish connection to server and start a session 95 | PendoSDK.initSdk('someAppKey', 96 | pendoParams, 97 | navigationOptions); 98 | ``` 99 | 100 | 3.x: 101 | 102 | ```javascript 103 | import { PendoSDK, NavigationLibraryType } from 'rn-pendo-sdk'; 104 | 105 | // only if using React Native Navigation 106 | import { Navigation } from "react-native-navigation"; 107 | 108 | 109 | // select the correct NavigationLibraryType according to your application 110 | const navigationOptions = {library: NavigationLibraryType.ReactNavigation}; 111 | const navigationOptions = {library: NavigationLibraryType.ReactNativeNavigation, navigation: Navigation}; 112 | const navigationOptions = {library: NavigationLibraryType.Other}; 113 | 114 | // establish connection to server 115 | PendoSDK.setup('someAppKey', navigationOptions); 116 | 117 | // start a session 118 | PendoSDK.startSession('someVisitorID', 119 | 'someAccountID', 120 | {'age': '25', 'country': 'USA'}, 121 | {'tier': '1', 'size': 'Enterprise'}); 122 | ``` 123 | 124 |
initSDKWithoutVisitor 132 | 133 | Call `setup` instead of `initSDKWithoutVisitor`. 134 | 135 | 2.x (deprecated): 136 | 137 | ```javascript 138 | import { PendoSDK, NavigationLibraryType } from 'rn-pendo-sdk'; 139 | 140 | // only if using React Native Navigation 141 | import { Navigation } from "react-native-navigation"; 142 | 143 | 144 | // select the correct NavigationLibraryType according to your application 145 | const navigationOptions = {library: NavigationLibraryType.ReactNavigation}; 146 | const navigationOptions = {library: NavigationLibraryType.ReactNativeNavigation, navigation: Navigation}; 147 | const navigationOptions = {library: NavigationLibraryType.Other}; 148 | 149 | // establish connection to server 150 | PendoSDK.initSDKWithoutVisitor('someAppKey', navigationOptions); 151 | ``` 152 | 153 | 3.x: 154 | 155 | ```javascript 156 | import { PendoSDK, NavigationLibraryType } from 'rn-pendo-sdk'; 157 | 158 | // only if using React Native Navigation 159 | import { Navigation } from "react-native-navigation"; 160 | 161 | 162 | // select the correct NavigationLibraryType according to your application 163 | const navigationOptions = {library: NavigationLibraryType.ReactNavigation}; 164 | const navigationOptions = {library: NavigationLibraryType.ReactNativeNavigation, navigation: Navigation}; 165 | const navigationOptions = {library: NavigationLibraryType.Other}; 166 | 167 | // establish connection to server 168 | PendoSDK.setup('someAppKey', navigationOptions); 169 | ``` 170 | 171 |
clearVisitor 179 | 180 | Call `startSession` with `null` values instead of `clearVisitor`. 181 | 182 | 2.x (deprecated): 183 | 184 | ```javascript 185 | // start a session with an anonymous visitor 186 | PendoSDK.clearVisitor() 187 | ``` 188 | 189 | 3.x: 190 | 191 | ```javascript 192 | // start a session with an anonymous visitor 193 | PendoSDK.startSession(null, null, null, null); 194 | ``` 195 | 196 |
switchVisitor 204 | 205 | Call `startSession` with a new visitor or account id instead of `switchVisitor`. 206 | 207 | 2.x (deprecated): 208 | 209 | ```javascript 210 | PendoSDK.switchVisitor('someVisitorID', 211 | 'someAccountID', 212 | {'age': '25', 'country': 'USA'}, 213 | {'tier': '1', 'size': 'Enterprise'}); 214 | ``` 215 | 216 | 3.x: 217 | 218 | ```javascript 219 | PendoSDK.startSession('someVisitorID', 220 | 'someAccountID', 221 | {'age': '25', 'country': 'USA'}, 222 | {'tier': '1', 'size': 'Enterprise'}); 223 | ``` 224 | 225 |
setAccountId 233 | 234 | Call `startSession` with the new account id value instead of `setAccountId`. 235 | 236 | 2.x (deprecated): 237 | 238 | ```javascript 239 | PendoSDK.setAccountId('someAccountID'); 240 | ``` 241 | 242 | 3.x: 243 | 244 | ```javascript 245 | // start a new session passing in the new accountId 246 | PendoSDK.startSession('someVisitorID', 247 | 'someAccountID', 248 | {'age': '25', 'country': 'USA'}, 249 | {'tier': '1', 'size': 'Enterprise'}); 250 | ``` 251 | 252 |
-------------------------------------------------------------------------------- /android/pnddocs/xamarin_maui-android.md: -------------------------------------------------------------------------------- 1 | # MAUI Android 2 | 3 | >[!NOTE] 4 | >The following integration instructions are relevant for SDK 3.0 or higher.
Follow our migration instructions to [upgrade from SDK 2.x to 3.0](/migration-docs/README.md) or refer to our [2.x integration instruction](https://github.com/pendo-io/pendo-mobile-sdk/blob/2.22.5/README.md). 5 | 6 | >[!IMPORTANT] 7 | >Requirements: 8 | >- .NET 8 - .NET 10 9 | >- Kotlin version 1.9.0 or higher 10 | 11 | ## Step 1. Install the Pendo SDK 12 | 13 | 1. In **Visual Studio** Solution Explorer, right-click on your shared project, then select "Add" - > "Add NuGet Packages…". 14 | 2. Search for: [**pendo-maui**](https://www.nuget.org/packages/pendo-maui) with latest version.
15 | 3. Press **Add Package**. 16 | 17 | 4. #### **Using Proguard / R8** 18 | 19 | - If you are using **ProGuard**, the rules that need to be added to ProGuard can be found here: [pendo-proguard.cfg](/android/pnddocs/pendo-proguard.cfg). 20 | 21 | 22 | - 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 your `app/proguard-rules.pro` file. 23 | The optimizations line should look like this: 24 | `-optimizations *other optimizations*,!code/allocation/variable` 25 | 26 | ## Step 2. Integrate with the Pendo SDK 27 | 28 | >[!NOTE] 29 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 30 | 31 | 1. Open the shared project **App.xaml.cs** 32 | 33 | Add the following under 'using': 34 | 35 | ```c# 36 | using PendoMAUIPlugin; 37 | ``` 38 | 39 | In the **protected override void OnStart()** method, add the following code: 40 | 41 | ```c# 42 | protected override void OnStart() 43 | { 44 | IPendoService pendo = PendoServiceFactory.CreatePendoService(); 45 | 46 | /** if your app supports additional Platforms other than iOS and Android 47 | verify the Pendo instance is not null */ 48 | if (pendo != null) { 49 | string apiKey = "YOUR_API_KEY_HERE"; 50 | pendo.Setup(apiKey); 51 | } 52 | 53 | ... 54 | 55 | } 56 | ``` 57 | 58 | 2. Start the visitor's session in the Page where your visitor is being identified (e.g., login, register, etc.). 59 | 60 | ```c# 61 | ... 62 | using PendoMAUIPlugin; 63 | ... 64 | 65 | namespace ExampleApp 66 | { 67 | class ExampleLoginClass 68 | { 69 | 70 | public void ExampleMethod() 71 | { 72 | ... 73 | 74 | IPendoService pendo = PendoServiceFactory.CreatePendoService(); 75 | 76 | /** if your app supports additional Platforms other than iOS and Android 77 | verify the Pendo instance is not null */ 78 | if (pendo != null) { 79 | var visitorId = "VISITOR-UNIQUE-ID"; 80 | var accountId = "ACCOUNT-UNIQUE-ID"; 81 | 82 | var visitorData = new Dictionary 83 | { 84 | { "age", 27 }, 85 | { "country", "USA" } 86 | }; 87 | 88 | var accountData = new Dictionary 89 | { 90 | { "Tier", 1 }, 91 | { "Size", "Enterprise" } 92 | }; 93 | 94 | pendo.StartSession(visitorId, accountId, visitorData, accountData); 95 | } 96 | 97 | ... 98 | 99 | } 100 | } 101 | ``` 102 | 103 | **visitorId**: a user identifier (e.g., John Smith) 104 | **visitorData**: the user metadata (e.g., email, phone, country, etc.) 105 | **accountId**: an affiliation of the user to a specific company or group (e.g., Acme inc.) 106 | **accountData** : the account metadata (e.g., tier, level, ARR, etc.) 107 | 108 | This code ends the previous mobile session (if applicable), starts a new mobile session, and retrieves all guides based on the provided information. 109 | 110 | >[!TIP] 111 | >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). 112 | 113 | 114 | 3. If your app is using **Gestures**, you must upgrade to SDK version 3.1 or above and then register **Pendo Effects** (PendoRoutingEffect, PendoPlatformEffect) in your **MauiProgram.cs** file as shown in the code below. 115 | 116 | ```c# 117 | ... 118 | using PendoMAUIPlugin; 119 | ... 120 | 121 | public static class MauiProgram 122 | { 123 | public static MauiApp CreateMauiApp() 124 | { 125 | var builder = MauiApp.CreateBuilder(); 126 | builder.UseMauiApp(); 127 | 128 | builder.ConfigureEffects(effects => 129 | { 130 | effects.Add(); 131 | }); 132 | return builder.Build(); 133 | } 134 | } 135 | ``` 136 | 137 | ## Step 3. Connect mobile device for tagging and testing 138 | 139 | >[!NOTE] 140 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 141 | 142 | This step enables page tagging. 143 | and guide testing capabilities. 144 | 145 | Add the following **activity** to the application **AndroidManifest.xml** in the `` tag: 146 | 147 | ```xml 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | ``` 157 | 158 | ## Step 4. Verify installation 159 | 1. Test using Visual Studio: 160 | Run the app. 161 | Review the Android Studio logcat and look for the following message: 162 | `Pendo SDK was successfully integrated and connected to the server.` 163 | 2. In the Pendo UI, go to `Settings` > `Subscription Settings`. 164 | 3. Select your application from the list. 165 | 4. Select the `Install Settings tab` and follow the instructions under `Verify Your Installation` to ensure you have successfully integrated the Pendo SDK. 166 | 5. Confirm that you can see your app as `Integrated` under subscription settings. 167 | 168 | 169 | ## Developer documentation 170 | 171 | - API documentation available [here](/api-documentation/xamarin-maui-apis.md) 172 | 173 | ## Troubleshooting 174 | 175 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 176 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 177 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 178 | -------------------------------------------------------------------------------- /ios/pnddocs/xamarin_maui-ios.md: -------------------------------------------------------------------------------- 1 | # MAUI iOS 2 | 3 | 4 | >[!NOTE] 5 | >The following integration instructions are relevant for SDK 3.0 or higher.
Follow our migration instructions to [upgrade from SDK 2.x to 3.0](/migration-docs/README.md) or refer to our [2.x integration instruction](https://github.com/pendo-io/pendo-mobile-sdk/blob/2.22.5/README.md). 6 | 7 | >[!IMPORTANT] 8 | >Requirements: 9 | >- .NET 8 - .NET 10 10 | 11 | ## Step 1. Install the Pendo SDK 12 | 13 | 1. In **Visual Studio** Solution Explorer, right-click on your shared project, then select "Add" - > "Add NuGet Packages…". 14 | 2. Search for: [**pendo-maui**](https://www.nuget.org/packages/pendo-maui) with latest version.
15 | 3. Press **Add Package**. 16 | 17 | 18 | ## Step 2. Integrate with the Pendo SDK 19 | 20 | >[!NOTE] 21 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 22 | 23 | 1. Open the shared project **App.xaml.cs**: 24 | 25 | Add the following under 'using': 26 | 27 | ```c# 28 | using PendoMAUIPlugin; 29 | ``` 30 | 31 | 32 | In the **protected override void OnStart()** method, add the following code: 33 | 34 | ```c# 35 | protected override void OnStart() 36 | { 37 | IPendoService pendo = PendoServiceFactory.CreatePendoService(); 38 | 39 | /** if your app supports additional Platforms other than iOS and Android 40 | verify the Pendo instance is not null */ 41 | if (pendo != null) { 42 | string apiKey = "YOUR_API_KEY_HERE"; 43 | pendo.Setup(apiKey); 44 | } 45 | 46 | ... 47 | 48 | } 49 | ``` 50 | 51 | 2. Start the visitor's Session in the Page where your visitor is being identified (e.g., login, register, etc.). 52 | 53 | ```c# 54 | using PendoMAUIPlugin; 55 | 56 | namespace ExampleApp 57 | { 58 | class ExampleLoginClass 59 | { 60 | 61 | public void MethodExample() 62 | { 63 | IPendoService pendo = PendoServiceFactory.CreatePendoService(); 64 | 65 | ... 66 | 67 | /** if your app supports additional Platforms other than iOS and Android 68 | verify the Pendo instance is not null */ 69 | if (pendo != null) { 70 | 71 | var visitorId = "VISITOR-UNIQUE-ID"; 72 | var accountId = "ACCOUNT-UNIQUE-ID"; 73 | 74 | var visitorData = new Dictionary 75 | { 76 | { "age", 27 }, 77 | { "country", "USA" } 78 | }; 79 | 80 | var accountData = new Dictionary 81 | { 82 | { "Tier", 1 }, 83 | { "Size", "Enterprise" } 84 | }; 85 | 86 | pendo.StartSession(visitorId, accountId, visitorData, accountData); 87 | 88 | } 89 | 90 | ... 91 | 92 | } 93 | } 94 | ``` 95 | 96 | **visitorId**: a user identifier (e.g., John Smith) 97 | **visitorData**: the user metadata (e.g., email, phone, country, etc.) 98 | **accountId**: an affiliation of the user to a specific company or group (e.g., Acme inc.) 99 | **accountData** : the account metadata (e.g., tier, level, ARR, etc.) 100 | 101 | This code ends the previous mobile session (if applicable), starts a new mobile session, and retrieves all guides based on the provided information. 102 | 103 | >[!TIP] 104 | >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). 105 | 106 | 3. If your app is using **Gestures**, you must upgrade to SDK version 3.1 or above and then register **Pendo Effects** (PendoRoutingEffect, PendoPlatformEffect) in your **MauiProgram.cs** file as shown in the code below. 107 | 108 | ```c# 109 | ... 110 | using PendoMAUIPlugin; 111 | ... 112 | 113 | public static class MauiProgram 114 | { 115 | public static MauiApp CreateMauiApp() 116 | { 117 | var builder = MauiApp.CreateBuilder(); 118 | builder.UseMauiApp(); 119 | 120 | builder.ConfigureEffects(effects => 121 | { 122 | effects.Add(); 123 | }); 124 | return builder.Build(); 125 | } 126 | } 127 | ``` 128 | 129 | ## Step 3. Connect mobile device for tagging and testing 130 | 131 | >[!NOTE] 132 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 133 | 134 | These steps enable Page tagging 135 | and guide testing capabilities. 136 | 137 | 1. Add a Pendo URL scheme to the **info.plist** file: 138 | 139 | Screenshot 2023-12-05 at 22 01 30 140 | 141 | Under the iOS App Target > open info.plist > if `URL Types` doesn't exist, click on 'Add new entry' of type `Array` and name it `URL types`. Create a new `Dictionary` inside the `Array` with two entries: 142 | - `URL identifier` of type `String` with a value that begins with `pendo` (ex. `pendo-scheme-d`). 143 | - `URL Schemes` of type `Array`. Add a `String` item with `YOUR_SCHEME_ID` as the value. 144 | 145 | 2. Add or modify the function **OpenURL**: 146 | 147 | Open ***AppDelegate.cs*** file and add ***using PendoMaui;*** 148 | add the following code under ***OpenUrl*** method: 149 | 150 | ```C# 151 | using PendoMaui; 152 | 153 | ... 154 | 155 | public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options) 156 | { 157 | if (url.Scheme.Contains("pendo")) 158 | { 159 | PendoManager.InitWithUrl(url.AbsoluteString); 160 | 161 | return true; 162 | } 163 | return base.OpenUrl(app, url, options); 164 | } 165 | ``` 166 | 167 | ## Step 4. Verify installation 168 | 169 | 1. Test using Visual Studio: 170 | Run the app. 171 | Review the Xcode console and look for the following message: 172 | `Pendo SDK was successfully integrated and connected to the server.` 173 | 2. In the Pendo UI, go to `Settings` > `Subscription Settings`. 174 | 3. Select your application from the list. 175 | 4. Select the `Install Settings tab` and follow the instructions under `Verify Your Installation` to ensure you have successfully integrated the Pendo SDK. 176 | 5. Confirm that you can see your app as `Integrated` under subscription settings. 177 | 178 | ## Developer documentation 179 | 180 | - API documentation available [here](/api-documentation/xamarin-maui-apis.md). 181 | 182 | ## Troubleshooting 183 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 184 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 185 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 186 | -------------------------------------------------------------------------------- /android/pnddocs/rnn-android.md: -------------------------------------------------------------------------------- 1 | # React Native Android using React Native Navigation 2 | 3 | >[!NOTE] 4 | >**Expo SDK** 41-53 using React Native Navigation 6+ is supported. See dedicated [Expo integration instructions](/android/pnddocs/expo_rnn-android.md). 5 | 6 | >[!IMPORTANT] 7 | >- We support a codeless solution for React Native 0.6-0.83 using react-native-navigation 6+. 8 | >- Support for React Native's New Architecture (Fabric) is available starting from version 3.7.2. 9 | 10 | >[!IMPORTANT] 11 | >Requirements: 12 | >- Android Gradle Plugin `8.0` or higher 13 | >- Kotlin version `1.9.0` or higher 14 | >- JAVA version `11` or higher 15 | >- minSdkVersion `21` or higher 16 | >- compileSDKVersion `35` or higher 17 | 18 | ## Step 1. Install the Pendo SDK 19 | 20 | 1. In the **root folder of your project**, add Pendo using one of your package managers: 21 | 22 | ```shell 23 | #example with npm 24 | npm install --save rn-pendo-sdk 25 | 26 | #example with yarn 27 | yarn add rn-pendo-sdk 28 | ``` 29 | 30 | 2. In the application **android/build.gradle** file: 31 | - **Add the Pendo Repository to the repositories section under the allprojects section or to the settings.gradle if using dependencyResolutionManagement:**: 32 | 33 | ```java 34 | allprojects { 35 | repositories { 36 | maven { 37 | url = uri("https://software.mobile.pendo.io/artifactory/androidx-release") 38 | } 39 | mavenCentral() 40 | } 41 | } 42 | ``` 43 | 44 | - **Minimum and compile Sdk versions**: 45 | If applicable, set your app to be compiled with **compileSdkVersion 35** or higher and **minSdkVersion 21** or higher: 46 | 47 | ```java 48 | android { 49 | minSdkVersion 21 50 | compileSdkVersion 35 51 | } 52 | ``` 53 | 54 | 3. In the application **AndroidManifest.xml** file. 55 | Add the following `` to the manifest in the `` tag: 56 | 57 | ```xml 58 | 59 | 60 | ``` 61 | 62 | 4. Modify Javascript minification 63 | 64 | When bundling for production, React Native minifies class and function names to reduce the size of the bundle. 65 | This means there is no access to the original component names that are used for the codeless solution. 66 | 67 | In the application **metro.config.js**, add the following statements in the transformer: 68 | 69 | ```javascript 70 | module.exports = { 71 | transformer: { 72 | // ... 73 | minifierConfig: { 74 | keep_classnames: true, // Preserve class names 75 | keep_fnames: true, // Preserve function names 76 | mangle: { 77 | keep_classnames: true, // Preserve class names 78 | keep_fnames: true, // Preserve function names 79 | } 80 | } 81 | } 82 | } 83 | ``` 84 | 85 | 5. #### Using ProGuard 86 | 87 | 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 your `app/proguard-rules.pro` file. The optimizations line should look like this: 88 | `-optimizations *other optimizations*,!code/allocation/variable` 89 | 90 | ## Step 2. Integrate with the Pendo SDK 91 | 92 | >[!NOTE] 93 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 94 | 95 | 1. In the application **main file (App.js/.ts/.tsx)**, add the following code: 96 | 97 | ```javascript 98 | import { PendoSDK, NavigationLibraryType } from 'rn-pendo-sdk'; 99 | import { Navigation } from "react-native-navigation"; 100 | 101 | function initPendo() { 102 | const navigationOptions = {library: NavigationLibraryType.ReactNativeNavigation, navigation: Navigation}; 103 | const pendoKey = 'YOUR_API_KEY_HERE'; 104 | //note the following API will only setup initial configuration, to start collect analytics use startSession 105 | PendoSDK.setup(pendoKey, navigationOptions); 106 | } 107 | initPendo(); 108 | ``` 109 | 110 | 2. Initialize Pendo where your visitor is being identified (e.g., login, register, etc.). 111 | 112 | ```javascript 113 | const visitorId = 'VISITOR-UNIQUE-ID'; 114 | const accountId = 'ACCOUNT-UNIQUE-ID'; 115 | const visitorData = {'Age': '25', 'Country': 'USA'}; 116 | const accountData = {'Tier': '1', 'Size': 'Enterprise'}; 117 | 118 | PendoSDK.startSession(visitorId, accountId, visitorData, accountData); 119 | ``` 120 | 121 | **Notes:** 122 | 123 | **visitorId**: a user identifier (e.g., John Smith) 124 | **visitorData**: the user metadata (e.g., email, phone, country, etc.) 125 | **accountId**: an affiliation of the user to a specific company or group (e.g., Acme inc.) 126 | **accountData**: the account metadata (e.g., tier, level, ARR, etc.) 127 | 128 | >[!TIP] 129 | >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). 130 | 131 | 132 | ## Step 3. Connect mobile device for tagging and testing 133 | 134 | >[!NOTE] 135 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 136 | 137 | This step enables Page tagging 138 | and guide testing capabilities. 139 | 140 | Add the following **activity** to the application **AndroidManifest.xml** in the `` tag: 141 | 142 | ```xml 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | ``` 152 | 153 | ## Step 4. Verify installation 154 | 155 | 1. Test using Android Studio: 156 | Run the app while attached to the Android Studio. 157 | Review the Android Studio logcat and look for the following message: 158 | `Pendo SDK was successfully integrated and connected to the server.` 159 | 2. In the Pendo UI, go to `Settings` > `Subscription Settings`. 160 | 3. Select your application from the list. 161 | 4. Select the `Install Settings tab` and follow the instructions under `Verify Your Installation` to ensure you have successfully integrated the Pendo SDK. 162 | 5. Confirm that you can see your app as `Integrated` under subscription settings. 163 | 164 | ## Developer documentation 165 | 166 | - API documentation available [here](/api-documentation/rn-apis.md). 167 | - Sample app with Pendo SDK integrated available here. 168 | 169 | ## Troubleshooting 170 | 171 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 172 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 173 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 174 | -------------------------------------------------------------------------------- /migration-docs/android-2.x-to-3.x-migration.md: -------------------------------------------------------------------------------- 1 | # Native Android migration from version 2.x to version 3.x 2 | 3 | ## Table of contents: 4 | - [Instructions for all native Android SDK integrations](#changes-relevant-to-all-native-android-apps) 5 | - [Instructions for secure metadata sessions using JWT](#changes-relevant-to-secure-metadata-sessions-using-jwt) 6 | 7 | ## Changes relevant to all native Android apps 8 | 9 | Follow these instructions to resolve breaking changes in your app: 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 272 | 273 |
Component / APIInstructions
Minimum
JAVA version

24 | 25 | 2.x (deprecated): `JAVA 8` 26 |
27 | 3.x: `JAVA 11` 28 | 29 |
Minimum
Kotlin version

37 | 38 | 2.x (deprecated): `1.7.20` 39 |
40 | 3.x: `1.9.0` 41 | 42 |
initSDK 50 | 51 | Replace `initSDK` by calling the `setup` API, followed by the `startSession` API. The `PendoInitParams` instance passed into `initSDK` no longer exists. The initialization parameters should be passed directly to the `setup` and `startSession` APIs. 52 | 53 | 2.x (deprecated): 54 | 55 | ```kotlin 56 | // set session parameters 57 | val pendoParams = Pendo.PendoInitParams() 58 | pendoParams.visitorId = "someVisitorID" 59 | pendoParams.accountId = "someAccountID" 60 | pendoParams.visitorData = mapOf("age" to 27, "country" to "USA") 61 | pendoParams.accountData = mapOf("tier" to 1, "size" to "Enterprise") 62 | 63 | // establish connection to server and start a session 64 | Pendo.initSDK( 65 | this, // Application or Activity 66 | "someAppKey", 67 | pendoParams 68 | ) 69 | ``` 70 | 71 | 3.x: 72 | 73 | ```kotlin 74 | // establish connection to server 75 | Pendo.setup( 76 | this, // Context 77 | "someAppKey", 78 | null, // PendoOptions 79 | null // PendoPhasesCallbackInterface 80 | ) 81 | 82 | // start a session 83 | Pendo.startSession( 84 | "someVisitorID", 85 | "someAccountID", 86 | mapOf("age" to 27, "country" to "USA"), 87 | mapOf("tier" to 1, "size" to "Enterprise") 88 | ) 89 | ``` 90 | 91 |
initSDKWithoutVisitor 99 | 100 | Call `setup` instead of `initSDKWithoutVisitor`. 101 | 102 | 2.x (deprecated): 103 | 104 | ```kotlin 105 | // establish connection to server 106 | Pendo.initSDKWithoutVisitor( 107 | this, // Application or Activity 108 | "someAppKey", 109 | null, // PendoOptions 110 | null // PendoPhasesCallbackInterface 111 | ) 112 | ``` 113 | 114 | 3.x: 115 | 116 | ```kotlin 117 | // establish connection to server 118 | Pendo.setup( 119 | this, // Context 120 | "someAppKey", 121 | null, // PendoOptions 122 | null // PendoPhasesCallbackInterface 123 | ) 124 | ``` 125 | 126 |
clearVisitor 134 | 135 | Call `startSession` with `null` values instead of `clearVisitor`. 136 | 137 | 2.x (deprecated): 138 | 139 | ```kotlin 140 | // start a session with an anonymous visitor 141 | Pendo.clearVisitor() 142 | ``` 143 | 144 | 3.x: 145 | 146 | ```kotlin 147 | // start a session with an anonymous visitor 148 | Pendo.startSession( 149 | null, // visitorId 150 | null, // accountId 151 | null, // visitorData 152 | null // accountData 153 | ) 154 | ``` 155 | 156 |
switchVisitor 164 | 165 | Call `startSession` with a new visitor or account id instead of `switchVisitor`. 166 | 167 | 2.x (deprecated): 168 | 169 | ```kotlin 170 | Pendo.switchVisitor( 171 | "someVisitorID", 172 | "someAccountID", 173 | mapOf("age" to 27, "country" to "USA"), 174 | mapOf("tier" to 1, "size" to "Enterprise") 175 | ) 176 | ``` 177 | 178 | 3.x: 179 | 180 | ```kotlin 181 | Pendo.startSession( 182 | "someVisitorID", 183 | "someAccountID", 184 | mapOf("age" to 27, "country" to "USA"), 185 | mapOf("tier" to 1, "size" to "Enterprise") 186 | ) 187 | ``` 188 | 189 |
setAccountId 197 | 198 | Call `startSession` with the new account id value instead of `setAccountId`. 199 | 200 | 2.x (deprecated): 201 | 202 | ```kotlin 203 | Pendo.setAccountId("someAccountID") 204 | ``` 205 | 206 | 3.x: 207 | 208 | ```kotlin 209 | // start a new session passing in the new accountId 210 | Pendo.startSession( 211 | "someVisitorID", 212 | "someAccountID", 213 | mapOf("age" to 27, "country" to "USA"), 214 | mapOf("tier" to 1, "size" to "Enterprise") 215 | ) 216 | ``` 217 | 218 |
pauseGuides
(without arguments)
226 | 227 | Pass a boolean value to `pauseGuides` to control dismissal of a guide if displayed when the API is invoked. By default, the deprecated API set the value to `true`. 228 | 229 | 2.x (deprecated): 230 | 231 | ```kotlin 232 | Pendo.pauseGuides() 233 | ``` 234 | 235 | 3.x: 236 | 237 | ```kotlin 238 | Pendo.pauseGuides(true) // true == dismiss any displayed guide 239 | ``` 240 | 241 |
isInitStarted callback 249 | 250 | The `onInitStarted` callback has been removed from the `PendoPhasesCallbackInterface`. 251 | 252 | 2.x (deprecated): 253 | 254 | ```kotlin 255 | class myPendoCallbackImplementation : PendoPhasesCallbackInterface { 256 | override fun onInitStarted() { ... } 257 | override fun onInitComplete() { ... } 258 | override fun onInitFailed() { ... } 259 | } 260 | ``` 261 | 262 | 3.x: 263 | 264 | ```kotlin 265 | class myPendoCallbackImplementation : PendoPhasesCallbackInterface { 266 | override fun onInitComplete() { ... } 267 | override fun onInitFailed() { ... } 268 | } 269 | ``` 270 | 271 |
274 | 275 | 276 | ## Changes relevant to secure metadata sessions using JWT 277 | 278 | JWT-related methods have been moved to a sub-namespace called `jwt`. 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 348 | 349 | 350 |
Component / APIInstructions
startSession 292 | 293 | 2.x (deprecated): 294 | 295 | ```kotlin 296 | Pendo.startSession("someJWT", "someSigningKeyName") 297 | ``` 298 | 299 | 3.x: 300 | 301 | ```kotlin 302 | Pendo.jwt.startSession("someJWT", "someSigningKeyName") 303 | ``` 304 | 305 |
setVisitorData 313 | 314 | 2.x (deprecated): 315 | 316 | ```kotlin 317 | Pendo.setVisitorData("someJWT", "someSigningKeyName") 318 | ``` 319 | 320 | 3.x: 321 | 322 | ```kotlin 323 | Pendo.jwt.setVisitorData("someJWT", "someSigningKeyName") 324 | ``` 325 | 326 |
setAccountData 334 | 335 | 2.x (deprecated): 336 | 337 | ```kotlin 338 | Pendo.setAccountData("someJWT", "someSigningKeyName") 339 | ``` 340 | 341 | 3.x: 342 | 343 | ```kotlin 344 | Pendo.jwt.setAccountData("someJWT", "someSigningKeyName") 345 | ``` 346 | 347 |
-------------------------------------------------------------------------------- /android/pnddocs/rn-android.md: -------------------------------------------------------------------------------- 1 | # React Native Android using React Navigation 2 | 3 | >[!NOTE] 4 | >**Expo SDK** 41-54 using React Navigation 5+ is supported. See dedicated [Expo integration instructions](/android/pnddocs/expo_rn-android.md). 5 | 6 | >[!IMPORTANT] 7 | >- We support a codeless solution for React Native 0.6-0.83 using react-navigation 5+. 8 | >- Support for React Native's New Architecture (Fabric) is available starting from version 3.7.2. 9 | 10 | >[!IMPORTANT] 11 | >Requirements: 12 | >- Android Gradle Plugin `8.0` or higher 13 | >- Kotlin version `1.9.0` or higher 14 | >- JAVA version `11` or higher 15 | >- minSdkVersion `21` or higher 16 | >- compileSDKVersion `35` or higher 17 | 18 | ## Step 1. Install the Pendo SDK 19 | 20 | 1. In the **root folder of your project**, add Pendo using one of your package managers: 21 | 22 | ```shell 23 | #example with npm 24 | npm install --save rn-pendo-sdk 25 | 26 | #example with yarn 27 | yarn add rn-pendo-sdk 28 | ``` 29 | 30 | 2. In the application **android/build.gradle** file: 31 | - **Add the Pendo Repository to the repositories section under the allprojects section or to the settings.gradle if using dependencyResolutionManagement:** 32 | 33 | ```java 34 | allprojects { 35 | repositories { 36 | maven { 37 | url = uri("https://software.mobile.pendo.io/artifactory/androidx-release") 38 | } 39 | mavenCentral() 40 | } 41 | } 42 | ``` 43 | 44 | - **Minimum and compile SDK versions** 45 | If applicable, set your app to be compiled with **compileSdkVersion 35** or higher and **minSdkVersion 21** or higher: 46 | 47 | ```java 48 | android { 49 | minSdkVersion 21 50 | compileSdkVersion 35 51 | } 52 | ``` 53 | 54 | 3. In the application **AndroidManifest.xml** file: 55 | Add the following `` to the manifest in the `` tag: 56 | 57 | ```xml 58 | 59 | 60 | ``` 61 | 62 | 4. #### Modify Javascript minification 63 | 64 | When bundling for production, React Native minifies class and function names to reduce the size of the bundle. This means there is no access to the original component names that are used for the codeless solution. 65 | 66 | In the application **metro.config.js**, add the following statements in the transformer: 67 | 68 | ```javascript 69 | module.exports = { 70 | transformer: { 71 | // ... 72 | minifierConfig: { 73 | keep_classnames: true, // Preserve class names 74 | keep_fnames: true, // Preserve function names 75 | mangle: { 76 | keep_classnames: true, // Preserve class names 77 | keep_fnames: true, // Preserve function names 78 | } 79 | } 80 | } 81 | } 82 | ``` 83 | 84 | 5. #### Using ProGuard 85 | 86 | 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 your `app/proguard-rules.pro` file. The optimizations line should look like this: 87 | `-optimizations *other optimizations*,!code/allocation/variable` 88 | 89 | ## Step 2. Integrate with the Pendo SDK 90 | 91 | >[!NOTE] 92 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 93 | 94 | 1. In the application **main file (App.js/.ts/.tsx)**, add the following code: 95 | 96 | ```javascript 97 | import { PendoSDK, NavigationLibraryType } from 'rn-pendo-sdk'; 98 | 99 | function initPendo() { 100 | const navigationOptions = {library: NavigationLibraryType.ReactNavigation}; 101 | const pendoKey = 'YOUR_API_KEY_HERE'; 102 | //note the following API will only setup initial configuration, to start collect analytics use startSession 103 | PendoSDK.setup(pendoKey, navigationOptions); 104 | } 105 | initPendo(); 106 | ``` 107 | 108 | 2. Initialize Pendo where your visitor is being identified (e.g., login, register, etc.). 109 | 110 | ```javascript 111 | const visitorId = 'VISITOR-UNIQUE-ID'; 112 | const accountId = 'ACCOUNT-UNIQUE-ID'; 113 | const visitorData = {'Age': '25', 'Country': 'USA'}; 114 | const accountData = {'Tier': '1', 'Size': 'Enterprise'}; 115 | 116 | PendoSDK.startSession(visitorId, accountId, visitorData, accountData); 117 | ``` 118 | 119 | 3. In the file where the `NavigationContainer` is created. 120 | 121 | Import `WithPendoReactNavigation`: 122 | 123 | ```javascript 124 | import {WithPendoReactNavigation} from 'rn-pendo-sdk' 125 | ``` 126 | 127 | Wrap `NavigationContainer` with `WithPendoReactNavigation` HOC: 128 | 129 | ```javascript 130 | const PendoNavigationContainer = WithPendoReactNavigation(NavigationContainer); 131 | ``` 132 | 133 | replace `NavigationContainer` tag with `PendoNavigationContainer` tag: 134 | 135 | ```javascript 136 | 137 | {/* Rest of your app code */} 138 | 139 | ``` 140 | 141 | **Notes:** 142 | 143 | **visitorId**: a user identifier (e.g., John Smith) 144 | **visitorData**: the user metadata (e.g., email, phone, country, etc.) 145 | **accountId**: an affiliation of the user to a specific company or group (e.g., Acme inc.) 146 | **accountData**: the account metadata (e.g., tier, level, ARR, etc.) 147 | 148 | >[!TIP] 149 | >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). 150 | 151 | 152 | ## Step 3. Connect mobile device for tagging and testing 153 | 154 | >[!NOTE] 155 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 156 | 157 | This step enables Page tagging 158 | and guide testing capabilities. 159 | 160 | Add the following **activity** to the application **AndroidManifest.xml** in the `` tag: 161 | 162 | ```xml 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | ``` 172 | 173 | ## Step 4. Verify installation 174 | 175 | 1. Test using Android Studio: 176 | Run the app while attached to the Android Studio. 177 | Review the Android Studio logcat and look for the following message: 178 | `Pendo SDK was successfully integrated and connected to the server.` 179 | 2. In the Pendo UI, go to `Settings` > `Subscription Settings`. 180 | 3. Select your application from the list. 181 | 4. Select the `Install Settings tab` and follow the instructions under `Verify Your Installation` to ensure you have successfully integrated the Pendo SDK. 182 | 5. Confirm that you can see your app as `Integrated` under subscription settings. 183 | 184 | ## Developer documentation 185 | 186 | - API documentation available [here](/api-documentation/rn-apis.md). 187 | - Sample app with Pendo SDK integrated available here. 188 | 189 | ## Troubleshooting 190 | 191 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 192 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 193 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 194 | -------------------------------------------------------------------------------- /ios/pnddocs/rnn-ios.md: -------------------------------------------------------------------------------- 1 | # React Native iOS using React Native Navigation 2 | 3 | >[!NOTE] 4 | >**Expo SDK** 41-54 using React Native Navigation 6+ is supported. See dedicated [Expo integration instructions](/ios/pnddocs/expo_rnn-ios.md). 5 | 6 | >[!IMPORTANT] 7 | >- We support a codeless solution for React Native 0.6-0.83 using react-native-navigation 6+. 8 | >- Support for React Native's New Architecture (Fabric) is available starting from version 3.7.2. 9 | 10 | >[!IMPORTANT] 11 | >Requirements: 12 | >- Deployment target of `iOS 11` or higher 13 | >- Swift Compatibility `5.7` or higher 14 | >- Xcode `14` or higher 15 | 16 | ## Step 1. Install the Pendo SDK 17 | 18 | 19 | 1. In the **root folder of your project**, add Pendo using one of your package managers: 20 | 21 | ```shell 22 | #example with npm 23 | npm install --save rn-pendo-sdk 24 | 25 | #example with yarn 26 | yarn add rn-pendo-sdk 27 | ``` 28 | 29 | 2. In the **iOS folder**, run the following command: 30 | 31 | ```shell script 32 | pod install 33 | ``` 34 | 35 | 3. **Modify Javascript minification** 36 | 37 | When bundling for production, React Native minifies class and function names to reduce the size of the bundle. This means that there is no access to the original component names that are used for the codeless solution. 38 | 39 | In the application **metro.config.js**, add the following statements in the transformer: 40 | 41 | ```javascript 42 | module.exports = { 43 | transformer: { 44 | // ... 45 | minifierConfig: { 46 | keep_classnames: true, // Preserve class names 47 | keep_fnames: true, // Preserve function names 48 | mangle: { 49 | keep_classnames: true, // Preserve class names 50 | keep_fnames: true, // Preserve function names 51 | } 52 | } 53 | } 54 | } 55 | ``` 56 | 57 | ## Step 2. Integrate with the Pendo SDK 58 | 59 | >[!NOTE] 60 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 61 | 62 | 1. In the application **main file (App.js/.ts/.tsx)**, add the following code: 63 | 64 | ```typescript 65 | import { PendoSDK, NavigationLibraryType } from 'rn-pendo-sdk'; 66 | import { Navigation } from "react-native-navigation"; 67 | 68 | function initPendo() { 69 | const navigationOptions = {library: NavigationLibraryType.ReactNativeNavigation, navigation: Navigation}; 70 | const pendoKey = 'YOUR_API_KEY_HERE'; 71 | //note the following API will only setup initial configuration, to start collect analytics use startSession 72 | PendoSDK.setup(pendoKey, navigationOptions); 73 | } 74 | initPendo(); 75 | ``` 76 | 77 | 78 | 2. Initialize Pendo where your visitor is being identified (e.g., login, register, etc.). 79 | 80 | ```typescript 81 | const visitorId = 'VISITOR-UNIQUE-ID'; 82 | const accountId = 'ACCOUNT-UNIQUE-ID'; 83 | const visitorData = {'Age': '25', 'Country': 'USA'}; 84 | const accountData = {'Tier': '1', 'Size': 'Enterprise'}; 85 | 86 | PendoSDK.startSession(visitorId, accountId, visitorData, accountData); 87 | ``` 88 | 89 | **Notes:** 90 | **visitorId**: a user identifier (e.g., John Smith) 91 | **visitorData**: the user metadata (e.g., email, phone, country, etc.) 92 | **accountId**: an affiliation of the user to a specific company or group (e.g., Acme inc.) 93 | **accountData**: the account metadata (e.g., tier, level, ARR, etc.) 94 | 95 | >[!TIP] 96 | >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). 97 | 98 | 99 | ## Step 3. Connect mobile device for tagging and testing 100 | 101 | >[!NOTE] 102 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 103 | 104 | These steps enable Page tagging 105 | and guide testing capabilities. 106 | 107 | 1. Add Pendo URL scheme to **info.plist** file: 108 | 109 | Under App Target > Info > URL Types, create a new URL by clicking the + button. 110 | Set **Identifier** to pendo-pairing or any name of your choosing. 111 | Set **URL Scheme** to `YOUR_SCHEME_ID`. 112 | 113 | Mobile Tagging
114 | 115 | 2. To enable pairing from the device: 116 | 117 | a. If using AppDelegate, add or modify the **openURL** function: 118 | 119 |
120 | Swift Instructions - Click to expand or collapse 121 | 122 | ```swift 123 | import Pendo 124 | 125 | ... 126 | 127 | func application(_ app: UIApplication,open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { 128 | if url.scheme?.range(of: "pendo") != nil { 129 | PendoManager.shared().initWith(url) 130 | return true 131 | } 132 | // your code here... 133 | return true 134 | } 135 | ``` 136 |
137 | 138 |
139 | Objective-C Instructions - Click to expand or collapse 140 | 141 | ```objective-c 142 | @import Pendo; 143 | 144 | - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { 145 | if ([[url scheme] containsString:@"pendo"]) { 146 | [[PendoManager sharedManager] initWithUrl:url]; 147 | return YES; 148 | } 149 | // your code here ... 150 | return YES; 151 | } 152 | ``` 153 |
154 | 155 |
156 | 157 | b. If using SceneDelegate, add or modify the **openURLContexts** function: 158 | 159 |
160 | Swift Instructions - Click to expand or collapse 161 | 162 | ```swift 163 | import Pendo 164 | 165 | ... 166 | 167 | func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { 168 | if let url = URLContexts.first?.url, url.scheme?.range(of: "pendo") != nil { 169 | PendoManager.shared().initWith(url) 170 | } 171 | } 172 | ``` 173 |
174 | 175 |
176 | Objective-C Instructions - Click to expand or collapse 177 | 178 | ```objectivec 179 | - (void)scene:(UIScene *)scene openURLContexts:(nonnull NSSet *)URLContexts { 180 | NSURL *url = [[URLContexts allObjects] firstObject].URL; 181 | if ([[url scheme] containsString:@"pendo"]) { 182 | [[PendoManager sharedManager] initWithUrl:url]; 183 | } 184 | // your code here ... 185 | } 186 | ``` 187 |
188 | 189 | ## Step 4. Verify installation 190 | 191 | 1. Test using Xcode: 192 | Run the app while attached to Xcode. 193 | Review the Xcode console and look for the following message: 194 | `Pendo Mobile SDK was successfully integrated and connected to the server.` 195 | 2. In the Pendo UI, go to `Settings` > `Subscription Settings`. 196 | 3. Select your application from the list. 197 | 4. Select the `Install Settings tab` and follow the instructions under `Verify Your Installation` to ensure you have successfully integrated the Pendo SDK. 198 | 5. Confirm that you can see your app as `Integrated` under subscription settings. 199 | 200 | ## Developer documentation 201 | 202 | - API documentation available [here](/api-documentation/rn-apis.md). 203 | - Sample app with Pendo SDK integrated available here.. 204 | 205 | ## Troubleshooting 206 | 207 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 208 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 209 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 210 | -------------------------------------------------------------------------------- /ios/pnddocs/rn-ios.md: -------------------------------------------------------------------------------- 1 | # React Native iOS using React Navigation 2 | 3 | >[!NOTE] 4 | >**Expo SDK** 41-54 using React Navigation 5+ is supported. See dedicated [Expo integration instructions](/ios/pnddocs/expo_rn-ios.md). 5 | 6 | >[!IMPORTANT] 7 | >- We support a codeless solution for React Native 0.6-0.83 using react-navigation 5+. 8 | >- Support for React Native's New Architecture (Fabric) is available starting from version 3.7.2. 9 | 10 | >[!IMPORTANT] 11 | >Requirements: 12 | >- Deployment target of `iOS 11` or higher 13 | >- Swift Compatibility `5.7` or higher 14 | >- Xcode `14` or higher 15 | 16 | ## Step 1. Install the Pendo SDK 17 | 18 | 1. In the **root folder of your project**, add Pendo using one of your package managers: 19 | 20 | ```shell 21 | #example with npm 22 | npm install --save rn-pendo-sdk 23 | 24 | #example with yarn 25 | yarn add rn-pendo-sdk 26 | ``` 27 | 28 | 2. In the **iOS folder**, run the following command: 29 | 30 | ```shell script 31 | pod install 32 | ``` 33 | 34 | 3. **Modify Javascript minification** 35 | 36 | When bundling for production, React Native minifies class and function names to reduce the size of the bundle. This means there is no access to the original component names that are used for the codeless solution. 37 | 38 | In the application **metro.config.js**, add the following statements in the transformer: 39 | 40 | ```javascript 41 | module.exports = { 42 | transformer: { 43 | // ... 44 | minifierConfig: { 45 | keep_classnames: true, // Preserve class names 46 | keep_fnames: true, // Preserve function names 47 | mangle: { 48 | keep_classnames: true, // Preserve class names 49 | keep_fnames: true, // Preserve function names 50 | } 51 | } 52 | } 53 | } 54 | ``` 55 | 56 | ## Step 2. Integrate with the Pendo SDK 57 | 58 | >[!NOTE] 59 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 60 | 1. In the application **main file (App.js/.ts/.tsx)**, add the following code: 61 | 62 | ```typescript 63 | import { PendoSDK, NavigationLibraryType } from 'rn-pendo-sdk'; 64 | 65 | function initPendo() { 66 | const navigationOptions = {library: NavigationLibraryType.ReactNavigation}; 67 | const pendoKey = 'YOUR_API_KEY_HERE'; 68 | //note the following API will only setup initial configuration, to start collect analytics use startSession 69 | PendoSDK.setup(pendoKey, navigationOptions); 70 | } 71 | initPendo(); 72 | ``` 73 | 2. Initialize Pendo where your visitor is being identified (e.g., login, register, etc.). 74 | 75 | ```typescript 76 | const visitorId = 'VISITOR-UNIQUE-ID'; 77 | const accountId = 'ACCOUNT-UNIQUE-ID'; 78 | const visitorData = {'Age': '25', 'Country': 'USA'}; 79 | const accountData = {'Tier': '1', 'Size': 'Enterprise'}; 80 | 81 | PendoSDK.startSession(visitorId, accountId, visitorData, accountData); 82 | ``` 83 | 84 | 3. In the file where the `NavigationContainer` is created. 85 | 86 | Import `WithPendoReactNavigation`: 87 | 88 | ```typescript 89 | import {WithPendoReactNavigation} from 'rn-pendo-sdk' 90 | ``` 91 | 92 | Wrap `NavigationContainer` with `WithPendoReactNavigation` HOC 93 | 94 | ```typescript 95 | const PendoNavigationContainer = WithPendoReactNavigation(NavigationContainer); 96 | ``` 97 | 98 | replace `NavigationContainer` tag with `PendoNavigationContainer` tag 99 | 100 | ```typescript 101 | 102 | {/* Rest of your app code */} 103 | 104 | ``` 105 | 106 | **Notes:** 107 | **visitorId**: a user identifier (e.g., John Smith) 108 | **visitorData**: the user metadata (e.g., email, phone, country, etc.) 109 | **accountId**: an affiliation of the user to a specific company or group (e.g., Acme inc.) 110 | **accountData**: the account metadata (e.g., tier, level, ARR, etc.) 111 | 112 | >[!TIP] 113 | >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). 114 | 115 | 116 | ## Step 3. Connect mobile device for tagging and testing 117 | 118 | >[!NOTE] 119 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 120 | 121 | These steps enable Page tagging 122 | and guide testing capabilities. 123 | 124 | 1. Add Pendo URL scheme to **info.plist** file: 125 | 126 | Under App Target > Info > URL Types, create a new URL by clicking the + button. 127 | Set **Identifier** to pendo-pairing or any name of your choosing. 128 | Set **URL Scheme** to `YOUR_SCHEME_ID`. 129 | 130 | Mobile Tagging
131 | 132 | 2. To enable pairing from the device: 133 | 134 | a. If using AppDelegate, add or modify the **openURL** function: 135 | 136 |
137 | Swift Instructions - Click to expand or collapse 138 | 139 | ```swift 140 | import Pendo 141 | 142 | ... 143 | 144 | func application(_ app: UIApplication,open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { 145 | if url.scheme?.range(of: "pendo") != nil { 146 | PendoManager.shared().initWith(url) 147 | return true 148 | } 149 | // your code here... 150 | return true 151 | } 152 | ``` 153 |
154 | 155 |
156 | Objective-C Instructions - Click to expand or collapse 157 | 158 | ```objective-c 159 | #import 160 | 161 | - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { 162 | if ([[url scheme] containsString:@"pendo"]) { 163 | [[PendoManager sharedManager] initWithUrl:url]; 164 | return YES; 165 | } 166 | // your code here ... 167 | return YES; 168 | } 169 | ``` 170 |
171 | 172 |
173 | 174 | b. If using SceneDelegate, add or modify the **openURLContexts** function: 175 | 176 |
177 | Swift Instructions - Click to expand or collapse 178 | 179 | ```swift 180 | import Pendo 181 | 182 | ... 183 | 184 | func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { 185 | if let url = URLContexts.first?.url, url.scheme?.range(of: "pendo") != nil { 186 | PendoManager.shared().initWith(url) 187 | } 188 | } 189 | ``` 190 |
191 | 192 |
193 | Objective-C Instructions - Click to expand or collapse 194 | 195 | ```objectivec 196 | - (void)scene:(UIScene *)scene openURLContexts:(nonnull NSSet *)URLContexts { 197 | NSURL *url = [[URLContexts allObjects] firstObject].URL; 198 | if ([[url scheme] containsString:@"pendo"]) { 199 | [[PendoManager sharedManager] initWithUrl:url]; 200 | } 201 | // your code here ... 202 | } 203 | ``` 204 |
205 | 206 | 207 | ## Step 4. Verify installation 208 | 209 | 1. Test using Xcode: 210 | Run the app while attached to Xcode. 211 | Review the Xcode console and look for the following message: 212 | `Pendo Mobile SDK was successfully integrated and connected to the server.` 213 | 2. In the Pendo UI, go to `Settings` > `Subscription Settings`. 214 | 3. Select your application from the list. 215 | 4. Select the `Install Settings tab` and follow the instructions under `Verify Your Installation` to ensure you have successfully integrated the Pendo SDK. 216 | 5. Confirm that you can see your app as `Integrated` under subscription settings. 217 | 218 | 219 | ## Developer documentation 220 | 221 | - API documentation available [here](/api-documentation/rn-apis.md). 222 | - Sample app with Pendo SDK integrated available here. 223 | 224 | ## Troubleshooting 225 | 226 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 227 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 228 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 229 | -------------------------------------------------------------------------------- /migration-docs/ios-2.x-to-3.x-migration.md: -------------------------------------------------------------------------------- 1 | # Native iOS migration from version 2.x to version 3.x 2 | 3 | ## Table of contents: 4 | - [Instructions for SwiftUI beta SDK](#mandatory-migration-instructions-for-the-swiftui-beta-sdk) 5 | - [Instructions for all native iOS SDK integrations](#changes-relevant-to-all-native-ios-apps) 6 | - [Instructions for secure metadata sessions using JWT](#changes-relevant-to-secure-metadata-sessions-using-jwt) 7 | 8 | ## Mandatory migration instructions for the SwiftUI beta SDK 9 | 10 | Pendo’s SwiftUI support is GA and its library is now merged into the iOS native SDK. The SwiftUI beta integration is no longer in use. If using SwiftUI beta support, follow the instructions in the table to switch over to the iOS native SDK. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 88 | 89 |
Component / API Instructions
Integration with Cocoapods 23 | 24 | In the podfile, replace `pod 'PendoSwiftUI'` with `pod 'Pendo'`. 25 | 26 |
Integration with SPM 34 | 35 | In the SPM, find the Pendo package and switch the Dependency Rule from `Branch` to `Up to Next Major Version`. 36 |
enableSwiftUI 45 | 46 | The `enableSwiftUI` method has been renamed to `pendoEnableSwiftUI`. 47 | 48 | 2.x (deprecated): 49 | 50 | ```swift 51 | someView.enableSwiftUI() 52 | ``` 53 | 3.0: 54 | 55 | ```swift 56 | someView.pendoEnableSwiftUI() 57 | ``` 58 | 59 | 3.1 (deprecated): 60 | 61 | The API has been deprecated and calling it will be ignored. The SDK automatically performs the logic removing the need to use this API. 62 | 63 |
enableClickAnalytics 72 | 73 | The `enableClickAnalytics` method has been renamed to `pendoRecognizeClickAnalytics`. 74 | 75 | 2.x (deprecated): 76 | 77 | ```swift 78 | someView.enableClickAnalytics() 79 | ``` 80 | 3.x: 81 | 82 | ```swift 83 | someView.pendoRecognizeClickAnalytics() 84 | ``` 85 | 86 | 87 |
90 | 91 | ## Changes relevant to all native iOS apps 92 | 93 | Follow these instructions to resolve breaking changes in your app: 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 342 | 343 |
Component / APIInstructions
Minimum
deployment target
108 | 109 | 2.x (deprecated): 110 | `iOS 9.0` 111 |
3.x: 112 | `iOS 11.0` 113 |
Minimum
xCode version
121 | 122 | 2.x (deprecated): 123 | `13` 124 |
3.x: 125 | `14` 126 |
Minimum
Swift compatibility
134 | 135 | 2.x (deprecated): 136 | `5.6` 137 |
3.x: 138 | `5.7` 139 |
initSDK 147 | 148 | Replace `initSDK` by calling the `setup` API, followed by the `startSession` API. The `PendoInitParams` instance passed into `initSDK` no longer exists. The initialization parameters should be passed directly to the `setup` and `startSession` APIs. 149 | 150 | 2.x (deprecated): 151 | 152 | ```swift 153 | // set session parameters 154 | let pendoInitParams = PendoInitParams() 155 | pendoInitParams.visitorId = "someVisitorID" 156 | pendoInitParams.accountId = "someAccountID" 157 | pendoInitParams.visitorData = ["age" : 27, "country" : "USA"] 158 | pendoInitParams.accountData = ["tier" : 1, "size" : "Enterprise"] 159 | 160 | // establish connection to server and start a session 161 | PendoManager.shared().initSDK("someAppKey", initParams: pendoInitParams) 162 | ``` 163 | 164 | 3.x: 165 | 166 | ```swift 167 | // establish connection to server 168 | PendoManager.shared().setup("someAppKey") 169 | 170 | // start a session 171 | PendoManager.shared().startSession("someVisitorID", 172 | accountId: "someAccountID", 173 | visitorData: ["age" : 27, "country" : "USA"], 174 | accountData: ["tier" : 1, "size" : "Enterprise"]) 175 | ``` 176 | 177 |
initSDKWithoutVisitor 185 | 186 | Call the `setup` API instead of `initSDKWithoutVisitor`. 187 | 188 | 2.x (deprecated): 189 | 190 | ```swift 191 | PendoManager.shared().initSDKWithoutVisitor("someAppKey", with: nil) 192 | ``` 193 | 3.x: 194 | 195 | ```swift 196 | PendoManager.shared().setup("someAppKey", with: nil) 197 | ``` 198 | 199 |
clearVisitor 207 | 208 | Call the `startSession` API with `nil` values instead of `clearVisitor`. 209 | 210 | 2.x (deprecated): 211 | 212 | ```swift 213 | // start a session with an anonymous visitor 214 | PendoManager.shared().clearVisitor() 215 | ``` 216 | 217 | 3.x: 218 | 219 | ```swift 220 | // start a session with an anonymous visitor 221 | PendoManager.shared().startSession(nil, 222 | accountId:nil, 223 | visitorData:nil, 224 | accountData:nil) 225 | ``` 226 | 227 |
switchVisitor 235 | 236 | Call the `startSession` API instead of `switchVisitor`. 237 | 238 | 2.x (deprecated): 239 | 240 | ```swift 241 | PendoManager.shared().switchVisitor("someVisitorID", 242 | accountId: "someAccountID", 243 | visitorData: ["age" : 27, "country" : "USA"], 244 | accountData: ["tier" : 1, "size" : "Enterprise"]) 245 | ``` 246 | 3.x: 247 | 248 | ```swift 249 | PendoManager.shared().startSession("someVisitorID", 250 | accountId: "someAccountID", 251 | visitorData: ["age" : 27, "country" : "USA"], 252 | accountData: ["tier" : 1, "size" : "Enterprise"]) 253 | ``` 254 | 255 |
pauseGuides
(without arguments)
263 | 264 | Pass a boolean value to `pauseGuides` to control dismissal of a guide if displayed when the API is invoked. By default, the deprecated API set the value to `true`. 265 | 266 | 2.x (deprecated): 267 | 268 | ```swift 269 | PendoManager.shared().pauseGuides() 270 | ``` 271 | 3.x: 272 | 273 | ```swift 274 | PendoManager.shared().pauseGuides(true) // true == dismiss any displayed guide 275 | ``` 276 | 277 |
enableClickAnalytics 285 | 286 | Call the `pendoRecognizeClickAnalytics` method on the UIView instance instead of passing the UIView instance as a parameter of `PendoManager.shared().enableClickAnalytics`. 287 | 288 | 2.x (deprecated): 289 | 290 | ```swift 291 | PendoManager.shared().enableClickAnalytics(someUIView) 292 | ``` 293 | 3.x: 294 | 295 | ```swift 296 | someUIView.pendoRecognizeClickAnalytics() 297 | ``` 298 | 299 |
accountId property setter 307 | 308 | Call `startSession` with the new account id value instead of setting the account id as a value of the `PendoManager.shared().accountId` property. 309 | 310 | 2.x (deprecated): 311 | 312 | ```swift 313 | PendoManager.shared().accountId = "someAccountId" 314 | ``` 315 | 3.x: 316 | 317 | ```swift 318 | PendoManager.shared().startSession("someVisitorID", 319 | accountId: "someAccountID", 320 | visitorData: ["age" : 27, "country" : "USA"], 321 | accountData: ["tier" : 1, "size" : "Enterprise"]) 322 | ``` 323 | 324 |
appkey property getter 332 | 333 | This property no longer exists. 334 | 335 | 2.x (deprecated): 336 | 337 | ```swift 338 | let appKey = PendoManager.shared().appKey 339 | ``` 340 | 341 |
344 | 345 | 346 | ## Changes relevant to secure metadata sessions using JWT 347 | 348 | JWT-related methods have been moved to a sub-namespace called `jwt`. 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 414 | 415 | 416 |
Component / APIInstructions
startSession 363 | 364 | 2.x (deprecated): 365 | 366 | ```swift 367 | PendoManager.shared().startSession("someJWT", "someSigningKeyName") 368 | ``` 369 | 3.x: 370 | 371 | ```swift 372 | PendoManager.shared().jwt.startSession("someJWT", "someSigningKeyName") 373 | ``` 374 | 375 |
setVisitorData 383 | 384 | 2.x (deprecated): 385 | 386 | ```swift 387 | PendoManager.shared().setVisitorData("someJWT", "someSigningKeyName") 388 | ``` 389 | 3.x: 390 | 391 | ```swift 392 | PendoManager.shared().jwt.setVisitorData("someJWT", "someSigningKeyName") 393 | ``` 394 |
setAccountData 402 | 403 | 2.x (deprecated): 404 | 405 | ```swift 406 | PendoManager.shared().setAccountData("someJWT", "someSigningKeyName") 407 | ``` 408 | 3.x: 409 | 410 | ```swift 411 | PendoManager.shared().jwt.setAccountData("someJWT", "someSigningKeyName") 412 | ``` 413 |
-------------------------------------------------------------------------------- /android/pnddocs/native-android.md: -------------------------------------------------------------------------------- 1 | # Native Android 2 | 3 | >[!NOTE] 4 | >The following integration instructions are relevant for SDK 3.0 or higher.
Follow our migration instructions to [upgrade from SDK 2.x to 3.0](/migration-docs/README.md) or refer to our [2.x integration instructions](https://github.com/pendo-io/pendo-mobile-sdk/blob/2.22.5/README.md). 5 | 6 | >[!IMPORTANT] 7 | >**Jetpack Compose GA** is now available (SDK 3.7.0+), offering: 8 | >- Retroactive analytics 9 | >- Self-serve tagging 10 | >- Full guides support 11 | > 12 | > If your application already uses Pendo, please review and implement the additional steps outlined in [Step 3](#step-3-tracking-jetpack-compose) to enable Jetpack Compose support within your existing integration. 13 | 14 | >[!IMPORTANT] 15 | >Requirements: 16 | >- Android Gradle Plugin `8.0` or higher 17 | >- Kotlin version `1.9.0` or higher 18 | >- JAVA version `11` or higher 19 | >- minSdkVersion `21` or higher 20 | >- compileSDKVersion `35` or higher 21 | > 22 | > If using Jetpack Compose: 23 | >- androidx.compose.ui:ui `1.5.0` or higher 24 | 25 | ## Step 1. Install Pendo SDK 26 | 27 | 1. #### Add the Pendo repository to the app's build.gradle or to the settings.gradle if using dependencyResolutionManagement: 28 | 29 | ```java 30 | repositories { 31 | maven { 32 | url = uri("https://software.mobile.pendo.io/artifactory/androidx-release") 33 | } 34 | mavenCentral() 35 | } 36 | ``` 37 | 38 | 2. #### Add Pendo as a dependency to **android/build.gradle** file: 39 | 40 | ```shell 41 | dependencies { 42 | implementation group:'sdk.pendo.io' , name:'pendoIO', version:'3.9.+', changing:true 43 | } 44 | ``` 45 | 46 | 3. **Minimum and compile SDK versions**: 47 | 48 | If applicable, set your app to be compiled with **compileSdkVersion 35** or higher and **minSdkVersion 21** or higher: 49 | 50 | ```java 51 | android { 52 | minSdkVersion 21 53 | compileSdkVersion 35 54 | } 55 | ``` 56 | 57 | 4. #### Using ProGuard 58 | 59 | 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 your `app/proguard-rules.pro` file. The optimizations line should look like this: 60 | `-optimizations *other optimizations*,!code/allocation/variable` 61 | 62 | ## Step 2. Integrate with the Pendo SDK 63 | 64 | >[!NOTE] 65 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 66 | 67 | 1. Set up Pendo in the **Application class**. 68 | 69 | The following code is required in the **onCreate** method: 70 | 71 | ```kotlin 72 | import sdk.pendo.io.*; 73 | 74 | val pendoApiKey = "YOUR_API_KEY_HERE" 75 | 76 | Pendo.setup( 77 | this, 78 | pendoApiKey, 79 | null, // PendoOptions (use only if instructed by Pendo support) 80 | null // PendoPhasesCallbackInterface (Optional) 81 | ) 82 | ``` 83 | 84 | 2. Initialize Pendo in the **Activity/fragment** where your visitor is being identified. 85 | 86 | ```kotlin 87 | val visitorId = "VISITOR-UNIQUE-ID" 88 | val accountId = "ACCOUNT-UNIQUE-ID" 89 | val visitorData = mapOf("age" to 27, "country" to "USA") 90 | val accountData = mapOf("Tier" to 1, "Size" to "Enterprise") 91 | 92 | Pendo.startSession( 93 | visitorId, 94 | accountId, 95 | visitorData, 96 | accountData 97 | ); 98 | ``` 99 | 100 | **visitorId**: a user identifier (e.g., John Smith) 101 | **visitorData**: the user metadata (e.g., email, phone, country, etc.) 102 | **accountId**: an affiliation of the user to a specific company or group (e.g., Acme inc.) 103 | **accountData** : the account metadata (e.g., tier, level, ARR, etc.) 104 |   105 | This code ends the previous mobile session (if applicable), starts a new mobile session, and retrieves all guides based on the provided information. 106 |   107 | 108 | >[!TIP] 109 | >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). 110 | 111 | ## Step 3. Tracking Jetpack Compose 112 | 113 | 1. **Add Compose Navigation Support** 114 | 115 | If you are using a **Compose Navigation**, add the following as soon as possible, immediately after `rememberNavController` in your app. 116 | 117 | 118 | - This step is required for the SDK to recognize Compose Pages in your app. 119 | - Navigation is limited to `androidx.navigation:navigation-compose` navigation. 120 | 121 | 122 | ```kotlin 123 | val navHostController = rememberNavController() 124 | .... 125 | 126 | LifecycleResumeEffect(null) { 127 | Pendo.setComposeNavigationController(navHostController.navController) 128 | 129 | onPauseOrDispose { 130 | Pendo.setComposeNavigationController(null) 131 | } 132 | } 133 | ``` 134 | 135 | >[!TIP] 136 | >We strongly recommend calling the navigation with your navigation component before calling startSession to ensure the SDK uses the correct screen ID. 137 | 138 | 2. **Drawer or ModalBottomSheetLayout Support (Add if applicable)** 139 | 140 | Automatic detection of Compose Drawer or ModalBottomSheetLayout in your app requires these steps: 141 | 142 | If you are using **Compose Navigation** add ``Modifier.pendoStateModifier(componentState)`` to your Drawer's or ModalBottomSheetLayout's modifier where componentState is the drawerState or sheetState. 143 | 144 | **Important:** To detect the dismissal of these components using this modifier, you must **specifically update the state** (bottomSheetState or drawerState) when you don’t want Pendo to detect the Page anymore. 145 | 146 | ```kotlin 147 | ModalBottomSheetLayout( 148 | sheetState = sheetState, 149 | sheetContent = { 150 | // Content of the bottom sheet 151 | modifier = Modifier.pendoStateModifier(sheetState), 152 | } 153 | ) 154 | ... 155 | ``` 156 | 157 | 3. **(Optional) Implement pendoTag in Jetpack Compose** 158 | 159 | PendoTags serve multiple purposes in identifying and tracking UI elements: 160 | 161 | - **Unique Feature identification:** It provides a unique identifier for Features during the tagging process. 162 | - **Manually enable click tracking:** For Composables you want to track as clicks that Pendo doesn't automatically detect, add pendoTag. You can also set mergeDescendants to true (default is false) to provide more attributes for better identification. 163 | - **Tooltip support:** Apply pendoTag to non-clickable Composable components to enable the presentation of tooltips. 164 | 165 | To implement pendoTag, add the following modifier to your relevant Composable components: 166 | 167 | ```kotlin 168 | someComposableObject( 169 | modifier = Modifier 170 | .pendoTag(UNIQUE_IDENTIFIER) 171 | ) 172 | ``` 173 | 174 | >[!NOTE] 175 | >pendoTags are case-sensitive. 176 | 177 | ## Step 4. Connect mobile device for tagging and testing 178 | 179 | >[!NOTE] 180 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 181 | 182 | This step enables Page tagging 183 | and guide testing capabilities. 184 | 185 | Add the following **activity** to the application **AndroidManifest.xml** in the `` tag: 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | ## Step 5. Verify installation 197 | 198 | 1. Test using Android Studio: 199 | Run the app while attached to the Android Studio. 200 | Review the Android Studio logcat and look for the following message: 201 | `Pendo SDK was successfully integrated and connected to the server.` 202 | 2. In the Pendo UI, go to `Settings` > `Subscription Settings`. 203 | 3. Select your application from the list. 204 | 4. Select the `Install Settings tab` and follow the instructions under `Verify Your Installation` to ensure you have successfully integrated the Pendo SDK. 205 | 5. Confirm that you can see your app as `Integrated` under subscription settings. 206 | 207 | ## Developer documentation 208 | 209 | - View our [API documentation](/api-documentation/native-android-apis.md). 210 | - See [Native application with Flutter components](/other/native-with-flutter-components.md) integration instructions. 211 | - If you need to manually install the SDK, refer to the [manual installation page](/android/pnddocs/android_sdk_manual_installation.md). 212 | 213 | ## Troubleshooting 214 | 215 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 216 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 217 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 218 | -------------------------------------------------------------------------------- /api-documentation/flutter-apis.md: -------------------------------------------------------------------------------- 1 | # Flutter public developer API documentation 2 | 3 | > [!IMPORTANT] 4 | >The `setup` API must be called before the `startSession` API.
5 | > All other APIs must be called after both the `setup` and `startSession` APIs, otherwise they will be ignored.
6 | >The `setDebugMode` API is the exception to that rule and may be called anywhere in the code. 7 | 8 | ### PendoSDK APIs 9 | [setup](#setup) ⇒ `void`
10 | [startSession](#startsession) ⇒ `void`
11 | [setVisitorData](#setvisitordata) ⇒ `void`
12 | [setAccountData](#setaccountdata) ⇒ `void`
13 | [endSession](#endsession) ⇒ `void`
14 | [track](#track) ⇒ `void`
15 | [pauseGuides](#pauseguides) ⇒ `void`
16 | [resumeGuides](#resumeguides) ⇒ `void`
17 | [dismissVisibleGuides](#dismissvisibleguides) ⇒ `void`
18 | [getDeviceId](#getdeviceid) ⇒ `String`
19 | [getVisitorId](#getvisitorid) ⇒ `String`
20 | [getAccountId](#getaccountid) ⇒ `String`
21 | [setDebugMode](#setdebugmode) ⇒ `void`
22 | 23 | ## PendoSDK APIs 24 | 25 | ### `setup` 26 | 27 | ```c# 28 | static Future setup(String appKey, {Map? pendoOptions}) async 29 | ``` 30 | 31 | >Establishes a connection with Pendo’s server. Call this API in your application’s main file (lib/main.dart). The setup method can only be called once during the application lifecycle. Calling this API is required before tracking sessions or invoking session-related APIs. 32 | 33 |
Details - Click to expand or collapse 34 | 35 |
36 | 37 | Class: PendoSDK 38 |
Kind: static method 39 |
40 | Returns: void 41 |
42 | 43 | | Param | Type | Description | 44 | | :---: | :---: | :--- | 45 | | appKey | String | The App Key is listed in your Pendo Subscription Settings in App Details | 46 | | pendoOptions | Map? | PendoOptions should be `null` unless instructed otherwise by Pendo Support | 47 | 48 | 49 | Example: 50 | 51 | ```c# 52 | await PendoSDK.setup('your.app.key', null); 53 | ``` 54 |
55 | 56 | 57 | ### `startSession` 58 | 59 | ```c# 60 | static Future startSession(String? visitorId, String? accountId, Map? visitorData, Map? accountData) async 61 | ``` 62 | 63 | >Starts a mobile session with the provided visitor and account information. If a session is already in progress, the current session will terminate and a new session will begin. The termination of the app will also terminate the session. 64 | 65 | >To generate an anonymous visitor, pass 'nil' as the visitorId. Visitor data and Account data are optional. 66 | 67 | > No action will be taken if the visitor and account IDs do not change when calling the startSession API during an ongoing session. 68 | 69 |
Details - Click to expand or collapse 70 | 71 |
72 | 73 | 74 | Class: PendoSDK 75 |
Kind: static method 76 |
77 | Returns: void 78 |
79 | 80 | | Param | Type | Description | 81 | | :---: | :---: | :--- | 82 | | visitorId | String? | The session visitor ID. For an anonymous visitor set to `null` | 83 | | accountId | String? | The session account ID | 84 | | visitorData | Dictionary? | Additional visitor metadata | 85 | | accountData | Dictionary? | Additional account metadata | 86 | 87 | 88 | Example: 89 | 90 | ```c# 91 | Map visitorData = {'age': 21, 'country': 'USA'}; 92 | Map accountData = {'Tier': 1, 'Size': 'Enterprise'}; 93 | 94 | await PendoSDK.startSession('John Doe', 'ACME', visitorData, accountData) 95 | ``` 96 | 97 |
98 | 99 | ### `setVisitorData` 100 | 101 | ```c# 102 | static Future setVisitorData(Map visitorData) async 103 | ``` 104 | 105 | >Updates the visitor metadata of the ongoing session. 106 | 107 |
Details - Click to expand or collapse 108 | 109 |
110 | 111 | 112 | Class: PendoSDK 113 |
Kind: static method 114 |
115 | Returns: void 116 |
117 | 118 | | Param | Type | Description | 119 | | :---: | :---: | :--- | 120 | | visitorData | Map | The visitor metadata to be updated | 121 | 122 | 123 | Example: 124 | 125 | ```c# 126 | Map visitorData = {'age': 25, 'country': 'UK', 'birthday': '01-01-1990'}; 127 | 128 | await PendoSDK.setVisitorData(visitorData) 129 | ``` 130 | 131 |
132 | 133 | ### `setAccountData` 134 | 135 | ```c# 136 | static Future setAccountData(Map accountData) async 137 | ``` 138 | 139 | >Updates the account metadata of the ongoing session. 140 | 141 |
Details - Click to expand or collapse 142 | 143 |
144 | 145 | 146 | Class: PendoSDK 147 |
Kind: static method 148 |
149 | Returns: void 150 |
151 | 152 | | Param | Type | Description | 153 | | :---: | :---: | :--- | 154 | | accountData | Map | The account metadata to be updated | 155 | 156 | 157 | Example: 158 | 159 | ```c# 160 | Map accountData = {'Tier': 2, 'size': 'Mid-Market', 'signing-date': '01-01-2020'}; 161 | 162 | await PendoSDK.setAccountData(accountData) 163 | 164 | ``` 165 | 166 |
167 | 168 | ### `endSession` 169 | 170 | ```c# 171 | static Future endSession() async 172 | ``` 173 | 174 | >Ends the active session and stops collecting analytics or showing guides to the user. A new session can be started by calling the startSession API. 175 | 176 | >This API is commonly used when the user logs out of your application. 177 | 178 | 179 | 180 |
Details - Click to expand or collapse 181 | 182 |
183 | 184 | 185 | Class: PendoSDK 186 |
Kind: static method 187 |
188 | Returns: void 189 |
190 | 191 | Example: 192 | 193 | ```c# 194 | await PendoSDK.endSession(); 195 | ``` 196 | 197 |
198 | 199 | ### `track` 200 | 201 | ```c# 202 | static Future track(String event, Map? properties) async 203 | ``` 204 | 205 | >Sends a track event with the specified properties. 206 | 207 |
208 | Details - Click to expand or collapse
209 | 210 | Class: PendoSDK
211 | Kind: static method
212 | Returns: void
213 |
214 | 215 | | Param | Type | Description | 216 | | :---: | :---: | :--- | 217 | | event | String | The track event name | 218 | | properties | Map? | Additional metadata to be sent as part of the track event | 219 | 220 | Example: 221 | 222 | ```c# 223 | await PendoSDK.track('App Opened', {'Theme': 'Dark Mode'}); 224 | ``` 225 |
226 | 227 | ### `pauseGuides` 228 | 229 | ```c# 230 | static Future pauseGuides(bool dismissGuides) async 231 | ``` 232 | 233 | >Pauses any guides from appearing during an active session. If the `dismissGuides` value is set to `true`, then any visible guide will be dismissed. Calling this API affects the current session. Starting a new session reverts this logic, enabling guides to be presented. 234 | 235 |
236 | Details - Click to expand or collapse
237 | Class: PendoSDK
238 | Kind: static method
239 | Returns: void
240 |
241 | 242 | | Param | Type | Description | 243 | | :---: | :---: | :--- | 244 | | dismissGuides | bool | Determines whether the displayed guide, if one is visible, is dismissed when pausing the display of the further guides | 245 | 246 | Example: 247 | 248 | ```c# 249 | await PendoSDK.pauseGuides(false); 250 | ``` 251 |
252 | 253 | 254 | ### `resumeGuides` 255 | 256 | ```c# 257 | static Future resumeGuides() async 258 | ``` 259 | 260 | >Resumes displaying guides during the ongoing session. This API reverses the logic of the `pauseGuides` API. 261 | 262 |
263 | Details - Click to expand or collapse 264 |
265 | Class: PendoSDK
266 | Kind: static method
267 | Returns: void
268 |
269 | Example: 270 | 271 | ```c# 272 | await PendoSDK.resumeGuides(); 273 | ``` 274 |
275 | 276 | ### `dismissVisibleGuides` 277 | 278 | ```c# 279 | static Future dismissVisibleGuides() async 280 | ``` 281 | 282 | >Dismisses any visible guide. 283 | 284 |
285 | Details - Click to expand or collapse
286 | Class: PendoSDK
287 | Kind: static method
288 | Returns: void
289 |
290 | Example: 291 | 292 | ```c# 293 | await PendoSDK.dismissVisibleGuides(); 294 | ``` 295 |
296 | 297 | ### `getDeviceId` 298 | 299 | ```c# 300 | static Future getDeviceId() async 301 | ``` 302 | 303 | >Returns the device's unique Pendo-generated ID. 304 | 305 |
306 | Details - Click to expand or collapse 307 |
308 | Class: PendoSDK
309 | Kind: static method
310 | Returns: String
311 |
312 | Example: 313 | 314 | ```c# 315 | await PendoSDK.getDeviceId(); 316 | ``` 317 |
318 | 319 | ### `getVisitorId` 320 | 321 | ```c# 322 | static Future getVisitorId() async 323 | ``` 324 | 325 | >Returns the ID of the visitor in the active session. 326 | 327 |
328 | Details - Click to expand or collapse 329 |
330 | Class: PendoSDK
331 | Kind: static method
332 | Returns: String
333 |
334 | Example: 335 | 336 | ```c# 337 | await PendoSDk.getVisitorId(); 338 | ``` 339 |
340 | 341 | ### `getAccountId` 342 | 343 | ```c# 344 | static Future getAccountId() async 345 | ``` 346 | 347 | >Returns the ID of the account in the active session. 348 | 349 |
350 | Details - Click to expand or collapse
351 | Class: PendoSDK
352 | Kind: static method
353 | Returns: String
354 |
355 | Example: 356 | 357 | ```c# 358 | await PendoSDK.getAccountId(); 359 | ``` 360 |
361 | 362 | ### `setDebugMode` 363 | 364 | ```c# 365 | static Future setDebugMode(bool isDebugEnabled) async 366 | ``` 367 | 368 | >Enable/disable debug logs from Pendo SDK. To debug the Pendo SDK we recommend calling this API before calling the setup API. 369 | 370 | >Debug logs are turned off by default. Releasing your production app with the debug logs enabled is not recommended and may have performance repercussions on your app. 371 | 372 |
Details - Click to expand or collapse 373 | 374 |
375 | 376 | Class: PendoSDK 377 |
Kind: static method 378 |
379 | Returns: void 380 |
381 | 382 | | Param | Type | Description | 383 | | :---: | :---: | :--- | 384 | | isDebugEnabled | bool | Set to `true` to enable debug logs, `false` to disable | 385 | 386 | 387 | Example: 388 | 389 | ```c# 390 | await PendoSDK.setDebugMode(true); 391 | await PendoSDK.setup("your.app.key", null); 392 | ``` 393 |
394 | -------------------------------------------------------------------------------- /ios/pnddocs/flutter-ios.md: -------------------------------------------------------------------------------- 1 | # Flutter iOS 2 | 3 | >[!IMPORTANT] 4 | >[Flutter Obfuscation issue](https://github.com/pendo-io/pendo-mobile-sdk/issues/196#issue-2605284796)

5 | >Migration from the track-event solution to the low-code solution: 6 | > 1. Refer to [Step 2](#step-2-pendo-sdk-integration) in the installation guide, and verify the addition of the navigationObserver and clickListener. 7 | > 2. The migration process will take up to 24 hours to complete and be reflected in Pendo, during the processing time, you will not be able to tag Pages and Features. 8 | 9 | >[!IMPORTANT] 10 | >Requirements: 11 | >- Flutter: ">=3.16.0" 12 | >- SDK: ">=3.2.0 < 4.0.0" 13 | > 14 | >Supported Navigation Libraries: 15 | > 16 | >- GoRouter 13.0 or higher 17 | >- AutoRoute 7.0 or higher 18 | 19 | ## Step 1. Add Pendo dependency 20 | In the root folder of your flutter app add the Pendo package: `flutter pub add pendo_sdk`. 21 | 22 | ## Step 2. Integrate with the Pendo SDK 23 | 24 | >[!NOTE] 25 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 26 | 27 | 1. For optimal integration place the following code at the beginning of your app's execution: 28 | ```dart 29 | import 'package:pendo_sdk/pendo_sdk.dart'; 30 | var pendoKey = 'YOUR_API_KEY_HERE'; 31 | await PendoSDK.setup(pendoKey); 32 | ``` 33 | 34 | 2. Initialize the Pendo Session where your visitor is being identified (e.g., login, register, etc.). 35 | ```dart 36 | import 'package:pendo_sdk/pendo_sdk.dart'; 37 | final String visitorId = 'John Smith'; 38 | final String accountId = 'Acme Inc.'; 39 | final dynamic visitorData = {'Age': '25', 'Country': 'USA'}; 40 | final dynamic accountData = {'Tier': '1', 'Size': 'Enterprise'}; 41 | 42 | await PendoSDK.startSession(visitorId, accountId, visitorData, accountData); 43 | ``` 44 | 45 | >[!TIP] 46 | >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). 47 | 48 | 3. Add Navigation Observers
49 | When using `Flutter Navigator API` add PendoNavigationObserver for each app Navigator: 50 | ```dart 51 | import 'package:pendo_sdk/pendo_sdk.dart'; 52 | // Observes the MaterialApp/CupertinoApp main Navigator 53 | return MaterialApp( 54 | ... 55 | navigatorObservers: [ 56 | PendoNavigationObserver() 57 | ],); 58 | 59 | // Observes the nested widget Navigator 60 | return Navigator( 61 | ... 62 | observers: [ 63 | PendoNavigationObserver() 64 | ],); 65 | ``` 66 | > [!TIP] 67 | > The Pendo SDK uses the `Route` name to uniquely identify each `Route`. Pendo highly recommends that you give a unique name to each route in the `RouteSettings`. The unique names must also be applied to the `showModalBottomSheet` api. 68 | 69 | **Navigation Types:**
70 | 71 | * **_GoRouter_** 72 | 73 | When using `GoRouter`, change the `setup` API call to include the correct navigation library, like so: 74 | ```dart 75 | PendoSDK.setup(pendoKey, navigationLibrary: NavigationLibrary.GoRouter); 76 | ``` 77 | When using `GoRouter`, apply the `addPendoListenerToDelegate()` to your `GoRouter` instance. 78 | Make sure to add it once (e.g., adding it in the build method will be less desired) 79 | ```dart 80 | import 'package:pendo_sdk/pendo_sdk.dart'; 81 | 82 | final GoRouter _router = GoRouter()..addPendoListenerToDelegate() 83 | 84 | class _AppState extends State { 85 | @override 86 | Widget build(BuildContext context) { 87 | return PendoActionListener( 88 | child: MaterialApp.router( 89 | routerConfig: _router, 90 | ), 91 | ); 92 | } 93 | } 94 | ``` 95 | 96 | > [!TIP] 97 | > Pendo SDK uses routerDelegate listener to track route change analytics, make sure your route is included in the GoRouter routes 98 | 99 | * **_AutoRoute_** 100 | 101 | When using `AutoRoute`, change the `setup` API call to include the correct navigation library, like so: 102 | ```dart 103 | PendoSDK.setup(pendoKey, navigationLibrary: NavigationLibrary.AutoRoute); 104 | ``` 105 | 106 | When using `AutoRoute`, apply the `addPendoListenerToDelegate()` to your `AutoRoute.config()` instance.
107 | Make sure to add it once (e.g., adding it in the build method will be less desired)
108 | 109 | ```dart 110 | import 'package:pendo_sdk/pendo_sdk.dart'; 111 | 112 | @AutoRouterConfig() 113 | class AppRouter extends RootStackRouter { 114 | @override 115 | List get routes => []; 116 | } 117 | 118 | final AppRouter _router = AppRouter()..config().addPendoListenerToDelegate(); 119 | 120 | class _AppState extends State { 121 | @override 122 | Widget build(BuildContext context) { 123 | return PendoActionListener( 124 | child: MaterialApp.router( 125 | routerConfig: _router.config(), 126 | ), 127 | ); 128 | } 129 | } 130 | ``` 131 | > [!TIP] 132 | > Pendo SDK uses routerDelegate listener to track route change analytics, make sure your route is included in the AutoRoute routes. 133 | 134 | 4. Add a click listener
135 | Wrap the main widget with a PendoActionListener in the root of the project: 136 | ```dart 137 | import 'package:pendo_sdk/pendo_sdk.dart'; 138 | 139 | Widget build(BuildContext context) { 140 | return PendoActionListener( // Use the PendoActionListener to track action clicks 141 | child: MaterialApp( 142 | title: 'Title', 143 | home: Provider( 144 | create: (context) => MyHomePageStore()..initList(), 145 | child: MyHomePage(title: Strings.appName), 146 | ), 147 | navigatorObservers: [PendoNavigationObserver()], // Use Pendo Observer to track the Navigator stack transitions 148 | ); 149 | ) 150 | } 151 | ``` 152 | 153 | > [!TIP] 154 | > You can use track events to programmatically notify Pendo of custom events of interest:
155 | 156 | ```dart 157 | import 'package:pendo_sdk/pendo_sdk.dart'; 158 | await PendoSDK.track('name', { 'firstProperty': 'firstPropertyValue', 'secondProperty': 'secondPropertyValue'}); 159 | ``` 160 | 161 | ## Step 3. Mobile device connectivity and testing 162 | 163 | >[!NOTE] 164 | > Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 165 | 166 | These steps enable guide testing capabilities. 167 | 168 | 1. **Add Pendo URL scheme to **info.plist** file:** 169 | 170 | Under App Target > Info > URL Types, create a new URL by clicking the + button. 171 | Set **Identifier** to pendo-pairing or any name of your choosing. 172 | Set **URL Scheme** to `YOUR_SCHEME_ID_HERE`. 173 | 174 | Mobile Tagging 175 | 176 | 2. **To enable pairing from the device:** 177 | 178 | In the AppDelegate file add or modify the **openURL** function: 179 | 180 |
181 | Swift Instructions - Click to expand or collapse 182 | 183 | ```swift 184 | import Pendo 185 | 186 | @UIApplicationMain 187 | class AppDelegate: FlutterAppDelegate { 188 | override func application(_ app: UIApplication,open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { 189 | if url.scheme?.range(of: "pendo") != nil { 190 | PendoManager.shared().initWith(url) 191 | return true 192 | } 193 | // your code here... 194 | return true 195 | } 196 | } 197 | ``` 198 |
199 | 200 |
201 | Objective-C Instructions - Click to expand or collapse 202 | 203 | ```objectivec 204 | @import Pendo; 205 | //your code 206 | - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { 207 | if ([[url scheme] containsString:@"pendo"]) { 208 | [[PendoManager sharedManager] initWithUrl:url]; 209 | return YES; 210 | } 211 | // your code here ... 212 | return YES; 213 | } 214 | ``` 215 |
216 | 217 | ## Step 4. Verify installation 218 | 219 | 1. Test using Xcode: 220 | Run the app while attached to Xcode. 221 | Review the Xcode console and look for the following message: 222 | `Pendo Mobile SDK was successfully integrated and connected to the server.` 223 | 2. In the Pendo UI, go to `Settings` > `Subscription Settings`. 224 | 3. Select your application from the list. 225 | 4. Select the `Install Settings tab` and follow the instructions under `Verify Your Installation` to ensure you have successfully integrated the Pendo SDK. 226 | 5. Confirm that you can see your app as `Integrated` under subscription settings. 227 | 228 | 229 | ## Using custom navigation widgets 230 | `With the release of version 3.6.2 custom navigation widget support was added.` 231 | 232 | To integrate custom navigation widgets (e.g., TabBar, BottomNavigationBar, PageView), follow these steps: 233 | 234 | 1. Implement `PendoCustomNavigationWidget` in your `StatefulWidget` class. 235 | 236 | 2. Implement `PendoNavigationState` in the corresponding state class. 237 | 238 | 3. Override `getPendoCustomNavigationInfo()` to provide details about the current navigation state. 239 | 240 | Example: 241 | 242 | ```dart 243 | class CUSTOM_STATEFULL_WIDGET extends StatefulWidget implements PendoCustomNavigationWidget { // Added for Pendo Support 244 | ... 245 | } 246 | 247 | class _CUSTOM_STATEFULL_WIDGET_STATE extends State implements PendoNavigationState { // Added for Pendo Support 248 | 249 | // Override this method to let Pendo get the info about the current selected state 250 | @override 251 | List getPendoCustomNavigationInfo() { 252 | List info = []; 253 | 254 | info.add(PendoCustomNavigationInfo( 255 | navigationWidgetType: PendoNavigationWidgetType.Top, // specifies widget location on the screen. this must be provided 256 | currentSelectedIndex: 1, // current selected index, optional 257 | numberOfIndexes: 5, // total number of indexes, optional 258 | currentSelectedTitle: 'first item', // unique title, optional 259 | selectedIconCode: 1234)); // unique number representing the image on the selected item, optional 260 | info.add(PendoCustomNavigationInfo( 261 | navigationWidgetType: PendoNavigationWidgetType.Middle, 262 | currentSelectedIndex: 2, 263 | numberOfIndexes: 3, 264 | currentSelectedTitle: 'second item', 265 | selectedIconCode: 2468)); 266 | info.add(PendoCustomNavigationInfo( 267 | navigationWidgetType: PendoNavigationWidgetType.Bottom, 268 | currentSelectedIndex: 3, 269 | numberOfIndexes: 6, 270 | currentSelectedTitle: 'third item', 271 | selectedIconCode: 1357)); 272 | 273 | return info; 274 | } 275 | } 276 | ``` 277 | 278 | ## Limitations 279 | - [Notes, Known Issues & Limitations](/other/flutter-notes-known-issues-limitations.md). 280 | - To support hybrid mode in Flutter, please open a ticket. 281 | 282 | ## Developer documentation 283 | 284 | - API documentation available [here](/api-documentation/flutter-apis.md). 285 | - See [Native application with Flutter components](/other/native-with-flutter-components.md) integration instructions. 286 | 287 | 288 | ## Troubleshooting 289 | 290 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 291 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 292 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 293 | 294 | -------------------------------------------------------------------------------- /android/pnddocs/flutter-android.md: -------------------------------------------------------------------------------- 1 | # Flutter Android 2 | 3 | >[!IMPORTANT] 4 | >[Flutter Obfuscation issue](https://github.com/pendo-io/pendo-mobile-sdk/issues/196#issue-2605284796)

5 | >Migration from the track-event solution to the low-code solution: 6 | > 1. Refer to [Step 2](#step-2-pendo-sdk-integration) in the installation guide, and verify the addition of the navigationObserver and clickListener. 7 | > 2. The migration process will take up to 24 hours to complete and be reflected in Pendo, during the processing time, you will not be able to tag Pages and Features. 8 | 9 | >[!IMPORTANT] 10 | >Requirements: 11 | >- Flutter: ">=3.16.0" 12 | >- SDK: ">=3.2.0 < 4.0.0" 13 | >- Android Gradle Plugin `8.0` or higher 14 | >- Kotlin version `1.9.0` or higher 15 | >- JAVA version `11` or higher 16 | >- minSdkVersion `21` or higher 17 | >- compileSDKVersion `35` or higher 18 | > 19 | >Supported Navigation Libraries: 20 | > 21 | >- GoRouter 13.0 or higher 22 | >- AutoRoute 7.0 or higher 23 | 24 | ## Step 1. Install Pendo SDK 25 | 26 | 1. In the **application folder**, run the following command: 27 | 28 | ```shell 29 | flutter pub add pendo_sdk 30 | ``` 31 | 32 | 2. In the application **android/build.gradle** file: 33 | 34 | - **Add the Pendo Repository to the repositories section under the allprojects section or to the settings.gradle if using dependencyResolutionManagement:** 35 | ```java 36 | allprojects { 37 | repositories { 38 | maven { 39 | url = uri("https://software.mobile.pendo.io/artifactory/androidx-release") 40 | } 41 | mavenCentral() 42 | } 43 | ``` 44 | 45 | - Minimum SDK Version: 46 | If applicable, set your app to be **minSdkVersion 21** or higher: 47 | 48 | ```java 49 | android { 50 | minSdkVersion 21 51 | } 52 | ``` 53 | 54 | 55 | 56 | 3. In the application **AndroidManifest.xml** file: 57 | Add the following `` to the manifest in the `` tag: 58 | 59 | ```xml 60 | 61 | 62 | ``` 63 | 64 | 4. Using ProGuard / R8 65 | - If you are using **ProGuard**, the rules that need to be added to ProGuard can be found here: [pendo-proguard.cfg](/android/pnddocs/pendo-proguard.cfg). 66 | 67 | 68 | - 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 your `app/proguard-rules.pro` file. 69 | The optimizations line should look like this: 70 | `-optimizations *other optimizations*,!code/allocation/variable` 71 | 72 | ## Step 2. Integrate with the Pendo SDK 73 | 74 | >[!NOTE] 75 | >Find your API key in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 76 | 77 | 1. For optimal integration place the following code at the beginning of your app's execution: 78 | 79 | ```dart 80 | import 'package:pendo_sdk/pendo_sdk.dart'; 81 | var pendoKey = 'YOUR_API_KEY_HERE'; 82 | await PendoSDK.setup(pendoKey); 83 | ``` 84 | 85 | 2. Initialize Pendo where your visitor is being identified (e.g., login, register, etc.). 86 | 87 | ```dart 88 | import 'package:pendo_sdk/pendo_sdk.dart'; 89 | final String visitorId = 'VISITOR-UNIQUE-ID'; 90 | final String accountId = 'ACCOUNT-UNIQUE-ID'; 91 | final Map visitorData = {'Age': '25', 'Country': 'USA'}; 92 | final Map accountData = {'Tier': '1', 'Size': 'Enterprise'}; 93 | 94 | await PendoSDK.startSession(visitorId, accountId, visitorData, accountData); 95 | ``` 96 | 97 | **Notes:** 98 | 99 | **visitorId**: a user identifier (e.g., John Smith) 100 | **visitorData**: the user metadata (e.g., email, phone, country, etc.) 101 | **accountId**: an affiliation of the user to a specific company or group (e.g., Acme inc.) 102 | **accountData**: the account metadata (e.g., tier, level, ARR, etc.) 103 | 104 | >[!TIP] 105 | >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). 106 | 107 | 108 | 3. Add Navigation Observers
109 | When using `Flutter Navigator API` add PendoNavigationObserver for each app Navigator: 110 | ```dart 111 | import 'package:pendo_sdk/pendo_sdk.dart'; 112 | // Observes the MaterialApp/CupertinoApp main Navigator 113 | return MaterialApp( 114 | ... 115 | navigatorObservers: [ 116 | PendoNavigationObserver() 117 | ],); 118 | 119 | // Observes the nested widget Navigator 120 | return Navigator( 121 | ... 122 | observers: [ 123 | PendoNavigationObserver() 124 | ],); 125 | ``` 126 | > [!TIP] 127 | > The Pendo SDK uses the `Route` name to uniquely identify each `Route`. Pendo highly recommends that you give a unique name to each route in the `RouteSettings`. The unique names must also be applied to the `showModalBottomSheet` api. 128 | 129 | **Navigation Types:**
130 | 131 | * **_GoRouter_** 132 | 133 | When using `GoRouter`, change the `setup` API call to include the correct navigation library, like so: 134 | ```dart 135 | PendoSDK.setup(pendoKey, navigationLibrary: NavigationLibrary.GoRouter); 136 | ``` 137 | 138 | When using `GoRouter`, apply the `addPendoListenerToDelegate()` to your `GoRouter` instance.
139 | Make sure to add it once (e.g., adding it in the build method will be less desired)
140 | 141 | ```dart 142 | import 'package:pendo_sdk/pendo_sdk.dart'; 143 | 144 | final GoRouter _router = GoRouter()..addPendoListenerToDelegate() 145 | 146 | class _AppState extends State { 147 | @override 148 | Widget build(BuildContext context) { 149 | return PendoActionListener( 150 | child: MaterialApp.router( 151 | routerConfig: _router, 152 | ), 153 | ); 154 | } 155 | } 156 | ``` 157 | 158 | > [!TIP] 159 | > Pendo SDK uses routerDelegate listener to track route change analytics, make sure your route is included in the GoRouter routes 160 | 161 | * **_AutoRoute_** 162 | 163 | When using `AutoRoute`, change the `setup` API call to include the correct navigation library, like so: 164 | ```dart 165 | PendoSDK.setup(pendoKey, navigationLibrary: NavigationLibrary.AutoRoute); 166 | ``` 167 | 168 | When using `AutoRoute`, apply the `addPendoListenerToDelegate()` to your `AutoRoute.config()` instance.
169 | Make sure to add it once (e.g., adding it in the build method will be less desired)
170 | 171 | ```dart 172 | import 'package:pendo_sdk/pendo_sdk.dart'; 173 | 174 | @AutoRouterConfig() 175 | class AppRouter extends RootStackRouter { 176 | @override 177 | List get routes => []; 178 | } 179 | 180 | final AppRouter _router = AppRouter()..config().addPendoListenerToDelegate(); 181 | 182 | class _AppState extends State { 183 | @override 184 | Widget build(BuildContext context) { 185 | return PendoActionListener( 186 | child: MaterialApp.router( 187 | routerConfig: _router.config(), 188 | ), 189 | ); 190 | } 191 | } 192 | ``` 193 | > [!TIP] 194 | > Pendo SDK uses routerDelegate listener to track route change analytics, make sure your route is included in the AutoRoute routes. 195 | 196 | 4. Add a click listener
197 | Wrap the main widget with a PendoActionListener in the root of the project: 198 | ```dart 199 | import 'package:pendo_sdk/pendo_sdk.dart'; 200 | Widget build(BuildContext context) { 201 | return PendoActionListener( // Use the PendoActionListener to track action clicks 202 | child: MaterialApp( 203 | title: 'Title', 204 | home: Provider( 205 | create: (context) => MyHomePageStore()..initList(), 206 | child: MyHomePage(title: Strings.appName), 207 | ), 208 | navigatorObservers: [PendoNavigationObserver()], // Use Pendo Observer to track the Navigator stack transitions 209 | ); 210 | ) 211 | } 212 | ``` 213 | 214 | >[!TIP] 215 | >You can use track events to programmatically notify Pendo of custom events of interest: 216 | ```dart 217 | import 'package:pendo_sdk/pendo_sdk.dart'; 218 | await PendoSDK.track('name', { 'firstProperty': 'firstPropertyValue', 'secondProperty': 'secondPropertyValue'}); 219 | ``` 220 | 221 | ## Step 3. Mobile device connectivity for testing 222 | 223 | >[!NOTE] 224 | >Find your scheme ID in the Pendo UI under `Settings` > `Subscription settings` > select an app > `App Details`. 225 | 226 | This step enables guide testing capabilities. 227 | 228 | Add the following **activity** to the application **AndroidManifest.xml** in the `` tag: 229 | 230 | ```xml 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | ``` 240 | 241 | ## Step 4. Verify installation 242 | 243 | 1. Test using Android Studio: 244 | Run the app while attached to the Android Studio. 245 | Review the Android Studio logcat and look for the following message: 246 | `Pendo SDK was successfully integrated and connected to the server.` 247 | 2. In the Pendo UI, go to `Settings` > `Subscription Settings`. 248 | 3. Select your application from the list. 249 | 4. Select the `Install Settings tab` and follow the instructions under `Verify Your Installation` to ensure you have successfully integrated the Pendo SDK. 250 | 5. Confirm that you can see your app as `Integrated` under subscription settings. 251 | 252 | ## Using custom navigation widgets 253 | `With the release of version 3.6.2 custom navigation widget support was added.` 254 | 255 | To integrate custom navigation widgets (e.g., TabBar, BottomNavigationBar, PageView), follow these steps: 256 | 257 | 1. Implement `PendoCustomNavigationWidget` in your `StatefulWidget` class. 258 | 259 | 2. Implement `PendoNavigationState` in the corresponding state class. 260 | 261 | 3. Override `getPendoCustomNavigationInfo()` to provide details about the current navigation state. 262 | 263 | Example: 264 | 265 | ```dart 266 | class CUSTOM_STATEFULL_WIDGET extends StatefulWidget implements PendoCustomNavigationWidget { // Added for Pendo Support 267 | ... 268 | } 269 | 270 | class _CUSTOM_STATEFULL_WIDGET_STATE extends State implements PendoNavigationState { // Added for Pendo Support 271 | 272 | // Override this method to let Pendo get the info about the current selected state 273 | @override 274 | List getPendoCustomNavigationInfo() { 275 | List info = []; 276 | 277 | info.add(PendoCustomNavigationInfo( 278 | navigationWidgetType: PendoNavigationWidgetType.Top, // specifies widget location on the screen. this must be provided 279 | currentSelectedIndex: 1, // current selected index, optional 280 | numberOfIndexes: 5, // total number of indexes, optional 281 | currentSelectedTitle: 'first item', // unique title, optional 282 | selectedIconCode: 1234)); // unique number representing the image on the selected item, optional 283 | info.add(PendoCustomNavigationInfo( 284 | navigationWidgetType: PendoNavigationWidgetType.Middle, 285 | currentSelectedIndex: 2, 286 | numberOfIndexes: 3, 287 | currentSelectedTitle: 'second item', 288 | selectedIconCode: 2468)); 289 | info.add(PendoCustomNavigationInfo( 290 | navigationWidgetType: PendoNavigationWidgetType.Bottom, 291 | currentSelectedIndex: 3, 292 | numberOfIndexes: 6, 293 | currentSelectedTitle: 'third item', 294 | selectedIconCode: 1357)); 295 | 296 | return info; 297 | } 298 | } 299 | ``` 300 | 301 | ## Limitations 302 | - [Notes, Known Issues & Limitations](/other/flutter-notes-known-issues-limitations.md). 303 | - To support hybrid mode in Flutter, please open a ticket. 304 | 305 | ## Developer documentation 306 | 307 | - API documentation available [here](/api-documentation/flutter-apis.md). 308 | - See [Native application with Flutter components](/other/native-with-flutter-components.md) integration instructions. 309 | 310 | 311 | ## Troubleshooting 312 | 313 | - For technical issues, please [review open issues](https://github.com/pendo-io/pendo-mobile-sdk/issues) or [submit a new issue](https://github.com/pendo-io/pendo-mobile-sdk/issues). 314 | - See our [release notes](https://developers.pendo.io/category/mobile-sdk/). 315 | - For additional documentation, visit our [Help Center](https://support.pendo.io/hc/en-us/categories/23324531103771-Mobile-implementation). 316 | -------------------------------------------------------------------------------- /api-documentation/xamarin-forms-apis.md: -------------------------------------------------------------------------------- 1 | # Xamarin Forms public developer API documentation 2 | 3 | > [!IMPORTANT] 4 | >The `Setup` API must be called before the `StartSession` API.
5 | > All other APIs must be called after both the `Setup` and `StartSession` APIs, otherwise they will be ignored.
6 | >The `SetDebugMode` API is the exception to that rule and may be called anywhere in the code. 7 | 8 | ### IPendoInterface APIs 9 | [IPendoInterface](#ipendointerface) ⇒ `IPendoInterface`
10 | [Setup](#setup) ⇒ `void`
11 | [StartSession](#startsession) ⇒ `void`
12 | [SetVisitorData](#setvisitordata) ⇒ `void`
13 | [SetAccountData](#setaccountdata) ⇒ `void`
14 | [EndSession](#endsession) ⇒ `void`
15 | [Track](#track) ⇒ `void`
16 | [PauseGuides](#pauseguides) ⇒ `void`
17 | [ResumeGuides](#resumeguides) ⇒ `void`
18 | [DismissVisibleGuides](#dismissvisibleguides) ⇒ `void`
19 | [GetDeviceId](#getdeviceid) ⇒ `string`
20 | [GetVisitorId](#getvisitorid) ⇒ `string`
21 | [GetAccountId](#getaccountid) ⇒ `string`
22 | [SetDebugMode](#setdebugmode) ⇒ `void`
23 | [ScreenContentChanged](#screencontentchanged) ⇒ `void`
24 | 25 | ## IPendoInterface APIs 26 | 27 | ### `IPendoInterface` 28 | 29 | ```c# 30 | interface IPendoInterface 31 | ``` 32 | 33 | >The interface of the Pendo shared instance. 34 | 35 |
Details - Click to expand or collapse 36 | 37 |
38 | 39 | Example: 40 | 41 | ```c# 42 | using PendoSDKXamarin; 43 | 44 | namespace ExampleApp 45 | { 46 | public partial class App : Application 47 | { 48 | private static IPendoInterface Pendo = DependencyService.Get(); 49 | 50 | // the rest of your code 51 | 52 | } 53 | } 54 | ``` 55 |
56 | 57 | ### `Setup` 58 | 59 | ```c# 60 | void Setup(string appKey) 61 | ``` 62 | 63 | >Establishes a connection with Pendo’s server. Call this API in your application’s OnStart() method. The setup method can only be called once during the application lifecycle. Calling this API is required before tracking sessions or invoking session-related APIs. 64 | 65 |
Details - Click to expand or collapse 66 | 67 |
68 | 69 | Class: PendoInterface 70 |
Kind: class method 71 |
Returns: void 72 |
73 | 74 | | Param | Type | Description | 75 | |:------:|:------:|:-------------------------------------------------------------------------| 76 | | appKey | string | The App Key is listed in your Pendo Subscription Settings in App Details | 77 | 78 |
79 | Example: 80 | 81 | ```c# 82 | Pendo.Setup("your.app.key"); 83 | ``` 84 |
85 | 86 | 87 | ### `StartSession` 88 | 89 | ```c# 90 | void StartSession(string visitorId, string accountId, Dictionary visitorData, Dictionary accountData) 91 | ``` 92 | 93 | >Starts a mobile session with the provided visitor and account information. If a session is already in progress, the current session will terminate and a new session will begin. The termination of the app will also terminate the session. 94 | 95 | >To generate an anonymous visitor, pass `null` as the visitorId. Visitor data and Account data are optional. 96 | 97 | > No action will be taken if the visitor and account IDs do not change when calling the startSession API during an ongoing session. 98 | 99 |
Details - Click to expand or collapse 100 | 101 |
102 | 103 | Class: PendoInterface 104 |
Kind: class method 105 |
Returns: void 106 |
107 | 108 | | Param | Type | Description | 109 | |:-----------:|:--------------------------:|:---------------------------------------------------------------| 110 | | visitorId | string | The session visitor ID. For an anonymous visitor set to `null` | 111 | | accountId | string | The session account ID | 112 | | visitorData | Dictionary | Additional visitor metadata | 113 | | accountData | Dictionary | Additional account metadata | 114 | 115 |
116 | Example: 117 | 118 | ```c# 119 | var visitorData = new Dictionary 120 | { 121 | { "age", 21 }, 122 | { "country", "USA" } 123 | }; 124 | 125 | var accountData = new Dictionary 126 | { 127 | { "Tier", 1 }, 128 | { "Size", "Enterprise" } 129 | }; 130 | 131 | Pendo.StartSession("John Doe", "ACME", visitorData, accountData); 132 | ``` 133 | 134 |
135 | 136 | ### `SetVisitorData` 137 | 138 | ```c# 139 | void SetVisitorData(Dictionary visitorData) 140 | ``` 141 | 142 | >Updates the visitor metadata of the ongoing session. 143 | 144 |
Details - Click to expand or collapse 145 | 146 |
147 | 148 | 149 | Class: PendoInterface 150 |
Kind: class method 151 |
Returns: void 152 |
153 | 154 | | Param | Type | Description | 155 | |:-----------:|:--------------------------:|:-----------------------------------| 156 | | visitorData | Dictionary | The visitor metadata to be updated | 157 | 158 |
159 | Example: 160 | 161 | ```c# 162 | var visitorData = new Dictionary 163 | { 164 | { "age", 25 }, 165 | { "country", "UK" }, 166 | { "birthday", "01-01-1990" } 167 | }; 168 | 169 | Pendo.SetVisitorData(visitorData); 170 | ``` 171 | 172 |
173 | 174 | ### `SetAccountData` 175 | 176 | ```c# 177 | void SetAccountData(Dictionary accountData) 178 | ``` 179 | 180 | >Updates the account metadata of the ongoing session. 181 | 182 |
Details - Click to expand or collapse 183 | 184 |
185 | 186 | 187 | Class: PendoInterface 188 |
Kind: class method 189 |
Returns: void 190 |
191 | 192 | | Param | Type | Description | 193 | |:-----------:|:--------------------------:|:-----------------------------------| 194 | | accountData | Dictionary | The account metadata to be updated | 195 | 196 |
197 | Example: 198 | 199 | ```c# 200 | var accountData = new Dictionary 201 | { 202 | { "Tier", 2 }, 203 | { "size", "Mid-Market" }, 204 | { "signing-date", "01-01-2020" } 205 | }; 206 | 207 | Pendo.SetAccountData(accountData); 208 | ``` 209 | 210 |
211 | 212 | ### `EndSession` 213 | 214 | ```c# 215 | void EndSession() 216 | ``` 217 | 218 | >Ends the active session and stops collecting analytics or showing guides to the user. A new session can be started by calling the startSession API. 219 | 220 | >This API is commonly used when the user logs out of your application. 221 | 222 | 223 | 224 |
Details - Click to expand or collapse 225 | 226 |
227 | 228 | 229 | Class: PendoInterface 230 |
Kind: class method 231 |
Returns: void 232 |
233 |
234 | Example: 235 | 236 | ```c# 237 | Pendo.EndSession(); 238 | ``` 239 | 240 |
241 | 242 | ### `Track` 243 | 244 | ```c# 245 | void Track(string eventName, 246 | Dictionary trackData) 247 | ``` 248 | 249 | >Sends a track event with the specified properties. 250 | 251 |
252 | Details - Click to expand or collapse
253 | 254 | Class: PendoInterface 255 |
Kind: class method 256 |
Returns: void 257 |
258 | 259 | | Param | Type | Description | 260 | |:----------:|:--------------------------:|:----------------------------------------------------------| 261 | | eventName | string | The track event name | 262 | | properties | Dictionary | Additional metadata to be sent as part of the track event | 263 | 264 |
265 | Example: 266 | 267 | ```c# 268 | var trackEventProperties = new Dictionary 269 | { 270 | { "Theme", "Dark Mode" }, 271 | }; 272 | 273 | Pendo.Track("App Opened", trackEventProperties); 274 | ``` 275 |
276 | 277 | ### `PauseGuides` 278 | 279 | ```c# 280 | void PauseGuides(bool dismissGuides) 281 | ``` 282 | 283 | >Pauses any guides from appearing during an active session. If the `DismissGuides` value is set to `true`, then any visible guide will be dismissed. Calling this API affects the current session. Starting a new session reverts this logic, enabling guides to be presented. 284 | 285 |
286 | Details - Click to expand or collapse
287 | Class: PendoInterface 288 |
Kind: class method 289 |
Returns: void 290 |
291 | 292 | | Param | Type | Description | 293 | |:-------------:|:----:|:-----------------------------------------------------------------------------------------------------------------------| 294 | | dismissGuides | bool | Determines whether the displayed guide, if one is visible, is dismissed when pausing the display of the further guides | 295 | 296 | Example: 297 | 298 | ```c# 299 | Pendo.PauseGuides(false); 300 | ``` 301 |
302 | 303 | 304 | ### `ResumeGuides` 305 | 306 | ```c# 307 | void ResumeGuides() 308 | ``` 309 | 310 | >Resumes displaying guides during the ongoing session. This API reverses the logic of the `PauseGuides` API. 311 | 312 |
313 | Details - Click to expand or collapse
314 | Class: PendoInterface 315 |
Kind: class method 316 |
Returns: void 317 |
318 |
319 | Example: 320 | 321 | ```c# 322 | Pendo.ResumeGuides(); 323 | ``` 324 |
325 | 326 | ### `DismissVisibleGuides` 327 | 328 | ```c# 329 | void DismissVisibleGuides() 330 | ``` 331 | 332 | >Dismisses any visible guide. 333 | 334 |
335 | Details - Click to expand or collapse
336 | Class: PendoInterface 337 |
Kind: class method 338 |
Returns: void 339 |
340 |
341 | Example: 342 | 343 | ```c# 344 | Pendo.DismissVisibleGuides(); 345 | ``` 346 |
347 | 348 | ### `GetDeviceId` 349 | 350 | ```c# 351 | string GetDeviceId() 352 | ``` 353 | 354 | >Returns the device's unique Pendo-generated ID. 355 | 356 |
357 | Details - Click to expand or collapse
358 | Class: PendoInterface 359 |
Kind: class method 360 |
Returns: string 361 |
362 |
363 | Example: 364 | 365 | ```c# 366 | Pendo.GetDeviceId(); 367 | ``` 368 |
369 | 370 | ### `GetVisitorId` 371 | 372 | ```c# 373 | string GetVisitorId() 374 | ``` 375 | 376 | >Returns the ID of the visitor in the active session. 377 | 378 |
379 | Details - Click to expand or collapse
380 | Class: PendoInterface 381 |
Kind: class method 382 |
Returns: string 383 |
384 |
385 | Example: 386 | 387 | ```c# 388 | Pendo.GetVisitorId(); 389 | ``` 390 |
391 | 392 | ### `GetAccountId` 393 | 394 | ```c# 395 | string GetAccountId() 396 | ``` 397 | 398 | >Returns the ID of the account in the active session. 399 | 400 |
401 | Details - Click to expand or collapse
402 | Class: PendoInterface 403 |
Kind: class method 404 |
Returns: string 405 |
406 |
407 | Example: 408 | 409 | ```c# 410 | Pendo.GetAccountId(); 411 | ``` 412 |
413 | 414 | ### `SetDebugMode` 415 | 416 | ```c# 417 | void SetDebugMode(bool isDebugEnabled) 418 | ``` 419 | 420 | >Enable/disable debug logs from Pendo SDK. To debug the Pendo SDK we recommend calling this API before calling the setup API. 421 | 422 | >Debug logs are turned off by default. Releasing your production app with the debug logs enabled is not recommended and may have performance repercussions on your app. 423 | 424 |
Details - Click to expand or collapse 425 | 426 |
427 | 428 | Class: PendoInterface 429 |
Kind: class method 430 |
Returns: void 431 |
432 | 433 | | Param | Type | Description | 434 | |:--------------:|:----:|:-------------------------------------------------------| 435 | | isDebugEnabled | bool | Set to `true` to enable debug logs, `false` to disable | 436 | 437 |
438 | Example: 439 | 440 | ```c# 441 | Pendo.SetDebugMode(true); 442 | Pendo.Setup("your.app.key"); 443 | ``` 444 |
445 | 446 | ### `ScreenContentChanged` 447 | 448 | ```c# 449 | void ScreenContentChanged() 450 | ``` 451 | 452 | >Rescans the Page enabling the Pendo SDK to identify changes that have occurred since the Page loaded. 453 | 454 | >Using this API is required to display tooltip guides and fix inaccurate analytics on elements that weren't present, or have been modified since the initial Page load. 455 | 456 | >The API does not generate an additional Page load event. 457 | 458 |
459 | Details - Click to expand or collapse
460 | Class: PendoInterface 461 |
Kind: class method 462 |
Returns: void 463 |
464 |
465 | Example: 466 | 467 | ```c# 468 | Pendo.ScreenContentChanged(); 469 | ``` 470 |
471 | -------------------------------------------------------------------------------- /api-documentation/xamarin-maui-apis.md: -------------------------------------------------------------------------------- 1 | # MAUI public developer API documentation 2 | 3 | > [!IMPORTANT] 4 | >The `Setup` API must be called before the `StartSession` API.
5 | > All other APIs must be called after both the `Setup` and `StartSession` APIs, otherwise they will be ignored.
6 | >The `SetDebugMode` API is the exception to that rule and may be called anywhere in the code. 7 | 8 | ### IPendoInterface APIs 9 | [IPendoService](#ipendoservice) ⇒ `IPendoService`
10 | [Setup](#setup) ⇒ `void`
11 | [StartSession](#startsession) ⇒ `void`
12 | [SetVisitorData](#setvisitordata) ⇒ `void`
13 | [SetAccountData](#setaccountdata) ⇒ `void`
14 | [EndSession](#endsession) ⇒ `void`
15 | [Track](#track) ⇒ `void`
16 | [PauseGuides](#pauseguides) ⇒ `void`
17 | [ResumeGuides](#resumeguides) ⇒ `void`
18 | [DismissVisibleGuides](#dismissvisibleguides) ⇒ `void`
19 | [GetDeviceId](#getdeviceid) ⇒ `string`
20 | [GetVisitorId](#getvisitorid) ⇒ `string`
21 | [GetAccountId](#getaccountid) ⇒ `string`
22 | [SetDebugMode](#setdebugmode) ⇒ `void`
23 | [ScreenContentChanged](#screencontentchanged) ⇒ `void`
24 | 25 | ## IPendoInterface APIs 26 | 27 | ### `IPendoService` 28 | 29 | ```c# 30 | interface IPendoService 31 | ``` 32 | 33 | >The interface of the Pendo shared instance. 34 | 35 |
Details - Click to expand or collapse 36 | 37 |
38 | 39 | Example: 40 | 41 | ```c# 42 | using PendoSDKXamarin; 43 | 44 | namespace ExampleApp 45 | { 46 | public partial class App : Application 47 | { 48 | IPendoService Pendo = PendoServiceFactory.CreatePendoService(); 49 | 50 | /** if your app supports additional Platforms other than iOS and Android 51 | verify the Pendo instance is not null */ 52 | 53 | if (pendo != null) { 54 | 55 | // pendo related code 56 | 57 | } 58 | 59 | // the rest of your code 60 | } 61 | } 62 | ``` 63 |
64 | 65 | ### `Setup` 66 | 67 | ```c# 68 | void Setup(string appKey) 69 | ``` 70 | 71 | >Establishes a connection with Pendo’s server. Call this API in your application’s OnStart() method. The setup method can only be called once during the application lifecycle. Calling this API is required before tracking sessions or invoking session-related APIs. 72 | 73 |
Details - Click to expand or collapse 74 | 75 |
76 | Interface: IPendoService 77 |
Class: PendoAndroidService/PendoiOSService 78 |
Kind: class method 79 |
Returns: void 80 |
81 | 82 | | Param | Type | Description | 83 | |:------:|:------:|:-------------------------------------------------------------------------| 84 | | appKey | string | The App Key is listed in your Pendo Subscription Settings in App Details | 85 | 86 | Example: 87 | 88 | ```c# 89 | Pendo.Setup("your.app.key"); 90 | ``` 91 |
92 | 93 | 94 | ### `StartSession` 95 | 96 | ```c# 97 | void StartSession(string visitorId, string accountId, Dictionary visitorData, Dictionary accountData) 98 | ``` 99 | 100 | >Starts a mobile session with the provided visitor and account information. If a session is already in progress, the current session will terminate and a new session will begin. The termination of the app will also terminate the session. 101 | 102 | >To generate an anonymous visitor, pass `null` as the visitorId. Visitor data and Account data are optional. 103 | 104 | > No action will be taken if the visitor and account IDs do not change when calling the startSession API during an ongoing session. 105 | 106 |
Details - Click to expand or collapse 107 | 108 |
109 | 110 | Interface: IPendoService 111 |
Class: PendoAndroidService/PendoiOSService 112 |
Kind: class method 113 |
Returns: void 114 |
115 | 116 | | Param | Type | Description | 117 | |:-----------:|:--------------------------:|:---------------------------------------------------------------| 118 | | visitorId | string | The session visitor ID. For an anonymous visitor set to `null` | 119 | | accountId | string | The session account ID | 120 | | visitorData | Dictionary | Additional visitor metadata | 121 | | accountData | Dictionary | Additional account metadata | 122 | 123 | 124 | Example: 125 | 126 | ```c# 127 | var visitorData = new Dictionary 128 | { 129 | { "age", 21 }, 130 | { "country", "USA" } 131 | }; 132 | 133 | var accountData = new Dictionary 134 | { 135 | { "Tier", 1 }, 136 | { "Size", "Enterprise" } 137 | }; 138 | 139 | Pendo.StartSession("John Doe", "ACME", visitorData, accountData); 140 | ``` 141 | 142 |
143 | 144 | ### `SetVisitorData` 145 | 146 | ```c# 147 | void SetVisitorData(Dictionary visitorData) 148 | ``` 149 | 150 | >Updates the visitor metadata of the ongoing session. 151 | 152 |
Details - Click to expand or collapse 153 | 154 |
155 | 156 | 157 | Interface: IPendoService 158 |
Class: PendoAndroidService/PendoiOSService 159 |
Kind: class method 160 |
Returns: void 161 |
162 | 163 | | Param | Type | Description | 164 | |:-----------:|:--------------------------:|:-----------------------------------| 165 | | visitorData | Dictionary | The visitor metadata to be updated | 166 | 167 | 168 | Example: 169 | 170 | ```c# 171 | var visitorData = new Dictionary 172 | { 173 | { "age", 25 }, 174 | { "country", "UK" }, 175 | { "birthday", "01-01-1990" } 176 | }; 177 | 178 | Pendo.SetVisitorData(visitorData); 179 | ``` 180 | 181 |
182 | 183 | ### `SetAccountData` 184 | 185 | ```c# 186 | void SetAccountData(Dictionary accountData) 187 | ``` 188 | 189 | >Updates the account metadata of the ongoing session. 190 | 191 |
Details - Click to expand or collapse 192 | 193 |
194 | 195 | 196 | Interface: IPendoService 197 |
Class: PendoAndroidService/PendoiOSService 198 |
Kind: class method 199 |
Returns: void 200 |
201 | 202 | | Param | Type | Description | 203 | |:-----------:|:--------------------------:|:-----------------------------------| 204 | | accountData | Dictionary | The account metadata to be updated | 205 | 206 | 207 | Example: 208 | 209 | ```c# 210 | var accountData = new Dictionary 211 | { 212 | { "Tier", 2 }, 213 | { "size", "Mid-Market" }, 214 | { "signing-date", "01-01-2020" } 215 | }; 216 | 217 | Pendo.SetAccountData(accountData); 218 | ``` 219 | 220 |
221 | 222 | ### `EndSession` 223 | 224 | ```c# 225 | void EndSession() 226 | ``` 227 | 228 | >Ends the active session and stops collecting analytics or showing guides to the user. A new session can be started by calling the startSession API. 229 | 230 | >This API is commonly used when the user logs out of your application. 231 | 232 | 233 | 234 |
Details - Click to expand or collapse 235 | 236 |
237 | 238 | 239 | Interface: IPendoService 240 |
Class: PendoAndroidService/PendoiOSService 241 |
Kind: class method 242 |
Returns: void 243 |
244 | 245 | Example: 246 | 247 | ```c# 248 | Pendo.EndSession(); 249 | ``` 250 | 251 |
252 | 253 | ### `Track` 254 | 255 | ```c# 256 | void Track(string eventName, 257 | Dictionary trackData) 258 | ``` 259 | 260 | >Sends a track event with the specified properties. 261 | 262 |
263 | Details - Click to expand or collapse
264 | 265 | Interface: IPendoService 266 |
Class: PendoAndroidService/PendoiOSService 267 |
Kind: class method 268 |
Returns: void 269 |
270 | 271 | | Param | Type | Description | 272 | |:----------:|:--------------------------:|:----------------------------------------------------------| 273 | | eventName | string | The track event name | 274 | | properties | Dictionary | Additional metadata to be sent as part of the track event | 275 | 276 | Example: 277 | 278 | ```c# 279 | var trackEventProperties = new Dictionary 280 | { 281 | { "Theme", "Dark Mode" }, 282 | }; 283 | 284 | Pendo.Track("App Opened", trackEventProperties); 285 | ``` 286 |
287 | 288 | ### `PauseGuides` 289 | 290 | ```c# 291 | void PauseGuides(bool dismissGuides) 292 | ``` 293 | 294 | >Pauses any guides from appearing during an active session. If the `DismissGuides` value is set to `true`, then any visible guide will be dismissed. Calling this API affects the current session. Starting a new session reverts this logic, enabling guides to be presented. 295 | 296 |
297 | Details - Click to expand or collapse
298 | 299 | Interface: IPendoService 300 |
Class: PendoAndroidService/PendoiOSService 301 |
Kind: class method 302 |
Returns: void 303 |
304 | 305 | | Param | Type | Description | 306 | |:-------------:|:----:|:------------------------------------------------------------------------------------------------------------------------| 307 | | dismissGuides | bool | Determines whether the displayed guide, if one is visible, is dismissed when pausing the display of the further guides | 308 | 309 | Example: 310 | 311 | ```c# 312 | Pendo.PauseGuides(false); 313 | ``` 314 |
315 | 316 | 317 | ### `ResumeGuides` 318 | 319 | ```c# 320 | void ResumeGuides() 321 | ``` 322 | 323 | >Resumes displaying guides during the ongoing session. This API reverses the logic of the `PauseGuides` API. 324 | 325 |
326 | Details - Click to expand or collapse
327 | Interface: IPendoService 328 |
Class: PendoAndroidService/PendoiOSService 329 |
Kind: class method 330 |
Returns: void 331 |
332 | 333 | Example: 334 | 335 | ```c# 336 | Pendo.ResumeGuides(); 337 | ``` 338 |
339 | 340 | ### `DismissVisibleGuides` 341 | 342 | ```c# 343 | void DismissVisibleGuides() 344 | ``` 345 | 346 | >Dismisses any visible guide. 347 | 348 |
349 | Details 350 |
351 | Interface: IPendoService 352 |
Class: PendoAndroidService/PendoiOSService 353 |
Kind: class method 354 |
Returns: void 355 |
356 | Example: 357 | 358 | ```c# 359 | Pendo.DismissVisibleGuides(); 360 | ``` 361 |
362 | 363 | ### `GetDeviceId` 364 | 365 | ```c# 366 | string GetDeviceId() 367 | ``` 368 | 369 | >Returns the device's unique Pendo-generated ID. 370 | 371 |
372 | Details - Click to expand or collapse
373 | Interface: IPendoService 374 |
Class: PendoAndroidService/PendoiOSService 375 |
Kind: class method 376 |
Returns: String 377 |
378 | Example: 379 | 380 | ```c# 381 | Pendo.GetDeviceId(); 382 | ``` 383 |
384 | 385 | ### `GetVisitorId` 386 | 387 | ```c# 388 | string GetVisitorId() 389 | ``` 390 | 391 | >Returns the ID of the visitor in the active session. 392 | 393 |
394 | Details - Click to expand or collapse
395 | Interface: IPendoService 396 |
Class: PendoAndroidService/PendoiOSService 397 |
Kind: class method 398 |
Returns: string 399 |
400 | Example: 401 | 402 | ```c# 403 | Pendo.GetVisitorId(); 404 | ``` 405 |
406 | 407 | ### `GetAccountId` 408 | 409 | ```c# 410 | string GetAccountId() 411 | ``` 412 | 413 | >Returns the ID of the account in the active session. 414 | 415 |
416 | Details - Click to expand or collapse
417 | Interface: IPendoService 418 |
Class: PendoAndroidService/PendoiOSService 419 |
Kind: class method 420 |
Returns: string 421 |
422 | Example: 423 | 424 | ```c# 425 | Pendo.GetAccountId(); 426 | ``` 427 |
428 | 429 | ### `SetDebugMode` 430 | 431 | ```c# 432 | void SetDebugMode(bool isDebugEnabled) 433 | ``` 434 | 435 | >Enable/disable debug logs from Pendo SDK. To debug the Pendo SDK we recommend calling this API before calling the setup API. 436 | 437 | >Debug logs are turned off by default. Releasing your production app with the debug logs enabled is not recommended and may have performance repercussions on your app. 438 | 439 |
Details - Click to expand or collapse 440 | 441 |
442 | 443 | Interface: IPendoService 444 |
Class: PendoAndroidService/PendoiOSService 445 |
Kind: class method 446 |
Returns: void 447 |
448 | 449 | | Param | Type | Description | 450 | |:--------------:|:----:|:-------------------------------------------------------| 451 | | isDebugEnabled | bool | Set to `true` to enable debug logs, `false` to disable | 452 | 453 | 454 | Example: 455 | 456 | ```c# 457 | Pendo.SetDebugMode(true); 458 | Pendo.Setup("your.app.key"); 459 | ``` 460 |
461 | 462 | ### `ScreenContentChanged` 463 | 464 | ```c# 465 | void ScreenContentChanged() 466 | ``` 467 | 468 | >Rescans the Page enabling the Pendo SDK to identify changes that have occurred since the Page loaded. 469 | 470 | >Using this API is required to display tooltip guides and fix inaccurate analytics on elements that weren't present, or have been modified since the initial Page load. 471 | 472 | >The API does not generate an additional Page load event. 473 | 474 |
475 | Details - Click to expand or collapse
476 | Interface: IPendoService 477 |
Class: PendoAndroidService/PendoiOSService 478 |
Kind: class method 479 |
Returns: void 480 |
481 | Example: 482 | 483 | ```c# 484 | Pendo.ScreenContentChanged(); 485 | ``` 486 |
487 | --------------------------------------------------------------------------------