Skip to content

Latest commit

 

History

History
340 lines (249 loc) · 14.8 KB

native-ios.md

File metadata and controls

340 lines (249 loc) · 14.8 KB

Native iOS

Cocoapods
GitHub tag (latest SemVer) Cocoapods Cocoapods Cocoapods

Note

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 or refer to our 2.x integration instruction.

Important

SwiftUI codeless solution is fully supported from iOS 15.
SwiftUI screen navigation tracking is available from iOS 13.

Important

Requirements:

  • Deployment target of iOS 11 or higher
  • Swift Compatibility 5.7 or higher
  • Xcode 14 or higher

Step 1. Add the Pendo SDK

Cocoapods:

  1. Open the Podfile.
  2. Add: pod 'Pendo'.

Swift Package Manager:

  1. Open File -> Add Packages.
  2. Search for: https://github.com/pendo-io/pendo-mobile-sdk.
  3. Select Up to Next Major Version.

Step 2. Establish a connection to Pendo's server on app launch

Note

The API Key can be found in your Pendo Subscription Settings in App Details.

Identify if your app project contains an AppDelegate file or a SceneDelegate file. Pure SwiftUI projects do not include either of these files. To use Pendo in your app, you will need to create one of them.

  1. If using the AppDelegate file, implement the following:

    Swift Instructions - Click to expand or collapse
    import UIKit
    import Pendo
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
        var window: UIWindow?
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            PendoManager.shared().setup("YOUR_API_KEY_HERE")
            //  your code here ...
            return true
        }
    }
    Objective-C Instructions - Click to expand or collapse
    #import "AppDelegate.h"
    #import "Pendo.h";    
    
    @implementation AppDelegate
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        [[PendoManager sharedManager] setup:@"YOUR_API_KEY_HERE"];
        //  your code here ...
        return YES;
    }
    @end

  1. If using the SceneDelegate file, implement the following:

    Swift Instructions - Click to expand or collapse
    import Pendo
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        PendoManager.shared().setup("YOUR_API_KEY_HERE")
        //  your code here ...
    }
    Objective-C Instructions - Click to expand or collapse
    #import "Pendo.h";    
    
    - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {}
        [[PendoManager sharedManager] setup:@"YOUR_API_KEY_HERE"];
        //  your code here ...
    }

Step 3. Start a new session to track a visitor and to display guides

To begin tracking a visitor's analytics and to display guides, call the startSession API. The call to the startSession API can be conducted immediately after calling the setup API or anywhere else in the code, such as completing the login process of your app.

Swift Instructions - Click to expand or collapse
var visitorId = "John Doe"
var accountId = "ACME"
var visitorData: [String : any Hashable] = ["age": 27, "country": "USA"]
var accountData: [String : any Hashable] = ["Tier": 1, "size": "Enterprise"]
PendoManager.shared().startSession(visitorId, accountId:accountId, visitorData:visitorData, accountData:accountData)  
Objective-C Instructions - Click to expand or collapse
[[PendoManager sharedManager] startSession:@"someVisitor" accountId:@"someAccount" visitorData:@{@"age": @27, @"country": @"USA"} accountData:@{@"Tier": @1, @"size": @"Enterprise"}];

Tip

To begin a session for an anonymous visitor, pass nil 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).

Supporting SwiftUI with older SDK (below 3.1) additional step

If using SDK below 3.1 the pendoEnableSwiftUI() modifier must be applied to the application rootView. If there are multiple rootViews (ex. usage of multiple UIHostingControllers), apply the modifier to each main rootView. See example below:

struct YourView: View {
    var body: some View {
        Text("RootView")
            .pendoEnableSwiftUI()
    }
}

Step 4. Configure Pairing Mode for tagging and testing

Note

The Scheme ID can be found in your Pendo Subscription Settings in App Details.

For additional information, see page tagging and guide testing.

Add the Pendo URL scheme to the info.plist file

Navigate to your App Target > Info > URL Types and create a new URL by clicking the plus (+) button.

Set the Identifier to pendo-pairing or an identifiable name of your choosing.
Set URL Scheme to YOUR_SCHEME_ID_HERE.

Mobile Tagging

Configure the app to connect to Pairing Mode

  1. If using AppDelegate, add or modify the openURL function:

    Swift Instructions - Click to expand or collapse
    import Pendo
    
    ...
    
    func application(_ app: UIApplication,open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        if url.scheme?.range(of: "pendo") != nil {
            PendoManager.shared().initWith(url)
            return true
        }
        // your code here...
        return true
    }
    Objective-C Instructions - Click to expand or collapse
         - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
             if ([[url scheme] containsString:@"pendo"]) {
                 [[PendoManager sharedManager] initWithUrl:url];
                 return YES;
             }
             //your code here...
             return YES;
         }                

  1. If using SceneDelegate, add or modify the openURLContexts function:

    Swift Instructions - Click to expand or collapse
    import Pendo
    
    ...
    
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        if let url = URLContexts.first?.url, url.scheme?.range(of: "pendo") != nil {
            PendoManager.shared().initWith(url)
        }
    }
    Objective-C Instructions - Click to expand or collapse
    - (void)scene:(UIScene *)scene openURLContexts:(nonnull NSSet<UIOpenURLContext *> *)URLContexts {
        NSURL *url = [[URLContexts allObjects] firstObject].URL;
        if ([[url scheme] containsString:@"pendo"]) {
            [[PendoManager sharedManager] initWithUrl:url];
        }
        //  your code here ...
    }

An additional required Step to configure Pairing Mode for SwiftUI

If the entry point to your app is a struct attributed with @main, your SwiftUI application will not respond to the method application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool.
To handle URL schemes in your SwiftUI app, add the .onOpenURL() modifier to your main view.

import Pendo

@main
struct YourApp: App {
    let persistenceController = PersistenceController.shared
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    var body: some Scene {
        return WindowGroup {
            TabView {
                YourView().tabItem {
                    Image("Icon")
                    Text("Text")
                }
            }
            .pendoEnableSwiftUI()
            .onOpenURL(perform: handleURL)
        }
    }
    
    func handleURL(_ url: URL) {
        _ = appDelegate.application(UIApplication.shared, open: url, options: [:])

    }
}

Step 5. Verify installation

  1. Test using Xcode:
    Run the app while attached to Xcode.
    Review the Xcode console and look for the following message:
    Pendo Mobile SDK was successfully integrated and connected to the server.
  2. In the Pendo UI, go to Settings > Subscription Settings.
  3. Select the Applications tab and then your application.
  4. Select the Install Settings tab and follow the instructions under Verify Your Installation to ensure you have successfully integrated the Pendo SDK.
  5. Confirm that you can see your app as Integrated under subscription settings.

SwiftUI limitations

SwiftUI tracking of page changes is based on the application events emitted by the following navigation components: NavigationView, TabView, NavigationLink, ActionSheet, Sheets or PopOvers. Rendering new views on the page will not be tracked by our SDK.

Specific Limitations

  1. List Elements: SwiftUI's handling of list elements can present limitations, particularly related to accessibility. If a list element has accessibility traits, it will be tracked by the SDK. However, if it does not, tracking might be incomplete or not occur at all. To ensure that list elements are properly tracked, make sure they have appropriate accessibility traits assigned.

  2. Padding in Stacks: When using padding in VStack or HStack without a background, the analytics tracking may not function correctly. This is because the padding alone doesn't generate trackable events. To work around this, you can explicitly call the pendoRecognizeClickAnalytics() API on the view to ensure that interactions are recorded.

  3. UIContextMenu: The UIContextMenu control is not supported in both Swift and SwiftUI. As a result, any interactions with context menus created using this control will not be tracked by the SDK.

Developer documentation

  • API documentation available here.

  • Integration of native with Flutter components available here.

  • Sample apps with examples of feature tagging and how Pendo analytics work.
    (pay attention to comments with PENDO CHANGE. In some cases these require minor changes of integration code or adding a background color)

SwiftUI Troubleshooting

Why aren't some elements being tagged correctly in SwiftUI?

  • Missing Accessibility Traits - Ensure that interactive elements, like buttons, have appropriate accessibility traits (e.g., .button). Adding these traits helps our SDK recognize and tag them correctly.

  • Embedding SwiftUI in UIKit - If you are using SwiftUI elements inside UIKit, enable pendoOptions.enableSwiftUIInsideUIKitScan. This option will help our SDK to recognize SwiftUI components within UIKit containers.

  • Using Our API - pendoRecognizeClickAnalytics() - Even with codeless solutions, sometimes it’s necessary to use our tagging API to manually recognize clickable views. Applying this API to the specific view can resolve tagging issues effectively.

Why do some of my SwiftUI screens have generic or irrelevant keywords in their screenId, and how can this be improved?

  • While we continue to refine screen identification for SwiftUI, make sure that your SwiftUI views are properly structured and identifiable. For now, this may require some manual adjustments to ensure each screen is tracked correctly.

I have noticed performance issues in my app after integrating Pendo SDK. What should I do?

  • Disable Unnecessary Information Collection - To improve performance, particularly on iPads, consider disabling some of the things Pendo collects while scanning your page:

    • Texts Collection - Set enableTextCollectionSwiftUI to false in pendoOptions:
    let options = PendoOptions()
    options.configs = ["enableTextCollectionSwiftUI": false]
    PendoManager.shared().setup(prodAppKey, with: options)
    
    • Pruning - To save time during scanning, set pendoOptions.enablePruning = false. This may help reduce the overhead.
  • Optimizing Scanning Depth - If performance issues persist, adjust the scan depth settings. Consult our support team to configure this setting for optimal performance.

General Troubleshooting