iOS SDK: Implementing Deep Links

Singular iOS SDK
Download
Singular iOS SDK version 10.1.2
Compatibility iOS 8+
Sample App

Our sample app includes a complete integration of the Singular SDK. Review the code to see how the different parts of the integration come together using best practices.

Integration Guides
  1. Basic Integration
  2. Tracking Events and Revenue
  3. Implementing Deep Links
  4. Adding SKAdNetwork Support
  5. Advanced Options

 

Introduction

Deep links are links that lead into specific content inside an app. When a user clicks a deep link on a device that has the app installed, the app opens and shows a specific product or experience.

Singular tracking links can include deep linking as well as deferred deep linking (see our Deep Linking FAQ and the Singular Links FAQ for more information).

The instructions below will show you how to:

  1. Access the tracking link that led to your app being opened,
  2. Read the deep link destination, and
  3. Show the appropriate content.

Notes:

Deep Linking Prerequisites

Singular uses iOS Universal Links for deep linking.

To enable Universal Links, follow the instructions in Singular Links Prerequisites.

Handling Deep Links

The Singular SDK offers deep link support through a handler that you set when you initialize the Singular SDK.

First, create the callback method for the handler. In the example below, we create a callback method called processDeeplink. The block signature is: void(^)(SingularLinkParams*). The SingularLinkParams contains the deep link destination, passthrough parameters, and whether the link is deferred or not.

Objective-C:

- (void)processDeeplink:(SingularLinkParams *)params {
    NSString* deeplink = [params getDeepLink];
    NSString* passthrough = [params getPassthrough];
    BOOL isDeferredDeeplink = [params isDeferred];
    // Add your code here
}

Next, add a call to the SDK initialization method:

  • If your app does NOT use scenes:

    Add a call to the SDK initialization method, including withSingularLinkHandler and your callback method, in both the didFinishLaunchingWithOptions and continueUserActivity entry points of your AppDelegate:

    // didFinishLaunchingWithOptions
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        [Singular startSession:@"YourAPIKey" withKey:@"YourAPISecret"
        andLaunchOptions:launchOptions
        withSingularLinkHandler:^(SingularLinkParams * params) {
        [self processDeeplink:params];
        }];
        return YES;
    }
    
    // continueUserActivity
    - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
    restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> *restorableObjects))restorationHandler {
        [Singular startSession:@"YourAPIKey" withKey:@"YourAPISecret"
        andUserActivity:userActivity
        withSingularLinkHandler:^(SingularLinkParams * params) {
            [self processDeeplink:params];
        }];
        return YES;
    }
     
    // openUrl
    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options{
        SingularConfig* config = [[SingularConfig alloc] initWithApiKey:@"YourAPIKey" andSecret:@"YourAPISecret"];
        config.singularLinksHandler = ^(SingularLinkParams * params) {
            [self processDeeplink:params];
        };
        config.openUrl = url;
        [Singular start:config];
        return YES;
    }

  • If your app uses scenes:

    1. Add a call to the SDK initialization method, including withSingularLinkHandler and your callback method, in the didFinishLaunchingWithOptions and entry point of your AppDelegate:
      // didFinishLaunchingWithOptions
      - (BOOL)application:(UIApplication *)application
         didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
          [Singular startSession:@"YourAPIKey" withKey:@"YourAPISecret"
          andLaunchOptions:launchOptions
          withSingularLinkHandler:^(SingularLinkParams * params) {
              [self processDeeplink:params];
          }];
          return YES;
      }
    2. Then call the SDK initialization method, including withSingularLinkHandler & andUserActivity, in both the willConnectToSession and continueUserActivity entry points of your SceneDelegate:
      // willConnectToSession
      - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session
         options:(UISceneConnectionOptions *)connectionOptions {
         NSUserActivity* userActivity =
         [[[connectionOptions userActivities] allObjects] firstObject];
      
         if(userActivity){
             [Singular startSession:@"YourAPIKey" withKey:@"YourAPISecret"
             andUserActivity:userActivity
             withSingularLinkHandler:^(SingularLinkParams * params) {
                 [self processDeeplink:params];
             }];
         }
      }
      
      // continueUserActivity
      - (void)scene:(UIScene *)scene
         continueUserActivity:(NSUserActivity *)userActivity{
         [Singular startSession:@"YourAPIKey" withKey:@"YourAPISecret"
         andUserActivity:userActivity
         withSingularLinkHandler:^(SingularLinkParams * params) {
             [self processDeeplink:params];
         }];
      }  
      
      // openURLContexts
      - (void)scene:(UIScene *)scene openURLContexts:(nonnull NSSet<UIOpenURLContext *> *)URLContexts {
         NSURL *url = [[URLContexts allObjects] firstObject].URL;
         
         if(url){
             SingularConfig* config = [[SingularConfig alloc] initWithApiKey:@"YourAPIKey" andSecret:@"YourAPISecret"];
          	 config.singularLinksHandler = ^(SingularLinkParams * params) {
                 [self processDeeplink:params];
          	 };
          	 config.openUrl = url;
          	 [Singular start:config];
         }
      }

Handling Deep Links with Legacy Links

If you are an older Singular customer, you may be using legacy tracking links (Singular's older tracking link mechanism) rather than the newer Singular Links. Legacy links are managed in the Create Link and View Links pages, and they also provide deep linking and deferred deep linking functionality.

If your organization uses legacy links, you can implement deep linking (and deferred deep linking) support through a different handler, registered using registerDeferredDeepLinkHandler.

registerDeferredDeepLinkHandler Method
Description Create a handler to read and process deep links and deferred deep links.
Signature + (void)registerDeferredDeepLinkHandler:(void (^)(NSString *deeplink))handler
Usage Example

Objective-C:

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Register the handler [Singular registerDeferredDeepLinkHandler:^(NSString
*deeplink) { NSLog(@"Deep link from Singular: %@", deeplink); [self processDeeplink:deeplink]; }]; return YES; } - (void)applicationDidBecomeActive:(UIApplication *)application { [Singular startSession:@"MyID" withKey:@"MyKey"]; } // Callback method for the handler - (void)processDeeplink:(NSString *)deeplink { // Implement your code here }

Notes:

  • You must register the handler before calling Singular startSession.
  • For optimal performance, we recommend placing Singular startSession calls before other processes/library initializations.
  • The block is called in the context of the main thread, so do not perform long-running operations inside the block.
  • If the Singular SDK does not receive a deep link value within 5 seconds, the SDK calls the block and passes a null value.

Handling Deep Links without Universal Links

The Singular SDK does provide support for Apple's older-style URI schema deep links, if your app does not support Apple's Universal Links.

To support URI schema deep links, add the following to the application function:

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    [Singular startSession:@"yourAPIKey" withKey:@"yourSecret" andLaunchURL:url];
    return YES;
}
Was this article helpful?