iOS Advanced Features

Create Content Reference

let buo = BranchUniversalObject.init(canonicalIdentifier: "content/12345")
buo.title = "My Content Title"
buo.contentDescription = "My Content Description"
buo.imageUrl = "https://lorempixel.com/400/400"
buo.publiclyIndex = true
buo.locallyIndex = true
buo.contentMetadata.customMetadata["key1"] = "value1"
BranchUniversalObject *buo = [[BranchUniversalObject alloc] initWithCanonicalIdentifier:@"content/12345"];
buo.title = @"My Content Title";
buo.contentDescription = @"My Content Description";
buo.imageUrl = @"https://lorempixel.com/400/400";
buo.publiclyIndex = YES;
buo.locallyIndex = YES;
buo.contentMetadata.customMetadata[@"key1"] = @"value1";

Create Link Reference

let lp: BranchLinkProperties = BranchLinkProperties()
lp.channel = "facebook"
lp.feature = "sharing"
lp.campaign = "content 123 launch"
lp.stage = "new user"
lp.tags = ["one", "two", "three"]

lp.addControlParam("$desktop_url", withValue: "http://example.com/desktop")
lp.addControlParam("$ios_url", withValue: "http://example.com/ios")
lp.addControlParam("$ipad_url", withValue: "http://example.com/ios")
lp.addControlParam("$android_url", withValue: "http://example.com/android")
lp.addControlParam("$match_duration", withValue: "2000")

lp.addControlParam("custom_data", withValue: "yes")
lp.addControlParam("look_at", withValue: "this")
lp.addControlParam("nav_to", withValue: "over here")
lp.addControlParam("random", withValue: UUID.init().uuidString)
BranchLinkProperties *lp = [[BranchLinkProperties alloc] init];
lp.feature = @"facebook";
lp.channel = @"sharing";
lp.campaign = @"content 123 launch";
lp.stage = @"new user";
lp.tags = @[@"one", @"two", @"three"];

[lp addControlParam:@"$desktop_url" withValue: @"http://example.com/desktop"];
[lp addControlParam:@"$ios_url" withValue: @"http://example.com/ios"];
[lp addControlParam:@"$ipad_url" withValue: @"http://example.com/ios"];
[lp addControlParam:@"$android_url" withValue: @"http://example.com/android"];
[lp addControlParam:@"$match_duration" withValue: @"2000"];

[lp addControlParam:@"custom_data" withValue: @"yes"];
[lp addControlParam:@"look_at" withValue: @"this"];
[lp addControlParam:@"nav_to" withValue: @"over here"];
[lp addControlParam:@"random" withValue: [[NSUUID UUID] UUIDString]];

Create Deep Link

buo.getShortUrl(with: lp) { (url, error) in
 print(url ?? "")
[buo getShortUrlWithLinkProperties:lp andCallback:^(NSString* url, NSError* error) {
    if (!error) {
        NSLog(@"@", url);
    }
}];

Share Deep Link

let message = "Check out this link"
buo.showShareSheet(with: lp, andShareText: message, from: self) { (activityType, completed) in
  print(activityType ?? "")
}
buo showShareSheetWithLinkProperties:lp andShareText:@"Super amazing thing I want to share!" fromViewController:self completion:^(NSString* activityType, BOOL completed) {
    NSLog(@"finished presenting");
}];

Read Deep Link

  • Retrieve Branch data from a deep link

  • Best practice to receive data from the listener (to prevent a race condition)

  • Returns deep link properties

// listener (within AppDelegate didFinishLaunchingWithOptions)
Branch.getInstance().initSession(launchOptions: launchOptions) { params, error in
  print(params as? [String: AnyObject] ?? {})
}

// latest
let sessionParams = Branch.getInstance().getLatestReferringParams()

// first
let installParams = Branch.getInstance().getFirstReferringParams()
[[Branch getInstance] initSessionWithLaunchOptions:launchOptions
                        andRegisterDeepLinkHandler:^(NSDictionary * _Nullable params,
                                                     NSError * _Nullable error) {
    if (!error) {
        //Referring params
        NSLog(@"Referring link params %@",params);
    }
}];

// latest
NSDictionary *sessionParams = [[Branch getInstance] getLatestReferringParams];

// first
NSDictionary *installParams =  [[Branch getInstance] getFirstReferringParams];

Navigate to Content

  • Handled within Branch.initSession()
// within AppDelegate application.didFinishLaunchingWithOptions
Branch.getInstance().initSession(launchOptions: launchOptions) { params , error in
  // Option 1: read deep link data
  guard let data = params as? [String: AnyObject] else { return }

  // Option 2: save deep link data to global model
  SomeCustomClass.sharedInstance.branchData = data

  // Option 3: display data
  let alert = UIAlertController(title: "Deep link data", message: "\(data)", preferredStyle: .alert)
  alert.addAction(UIAlertAction(title: "Okay", style: .default, handler: nil))
  self.window?.rootViewController?.present(alert, animated: true, completion: nil)

  // Option 4: navigate to view controller
  guard let options = data["nav_to"] as? String else { return }
  switch options {
      case "landing_page": self.window?.rootViewController?.present( SecondViewController(), animated: true, completion: nil)
      case "tutorial": self.window?.rootViewController?.present( SecondViewController(), animated: true, completion: nil)
      case "content": self.window?.rootViewController?.present( SecondViewController(), animated: true, completion: nil)
      default: break
  }
}
// within AppDelegate application.didFinishLaunchingWithOptions
[[Branch getInstance] initSessionWithLaunchOptions:launchOptions andRegisterDeepLinkHandler:^(NSDictionary * _Nonnull params, NSError * _Nullable error) {
  // Option 1: read deep link data
  NSLog(@"%@", params);

  // Option 2: save deep link data to global model
  NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
  [defaults setObject:params.description forKey:@"BranchData"];
  [defaults synchronize];

  // Option 3: display data
  UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"Title" message:params.description preferredStyle:UIAlertControllerStyleAlert];
  UIAlertAction *button = [UIAlertAction actionWithTitle:@"Deep Link Data" style:UIAlertActionStyleDefault handler:nil];
  [alert addAction:button];
  [self.window.rootViewController presentViewController:alert animated:YES completion:nil];

  // Option 4: navigate to view controller
  if ([params objectForKey:@"navHere"]) {
    ViewController *anotherViewController = [[ViewController alloc] initWithNibName:@"anotherViewController" bundle:nil];
    [self.window.rootViewController presentViewController:anotherViewController animated:YES completion:nil];
  }
}];

Display

buo.automaticallyListOnSpotlight = true
buo.automaticallyListOnSpotlight = YES;

Track content

BranchEvent.standardEvent(.viewItem, withContentItem: buo).logEvent()
[[BranchEvent standardEvent:BranchStandardEventViewItem withContentItem:buo] logEvent];

Track users

  • Sets the identity of a user (email, ID, UUID, etc) for events, deep links, and referrals

Invoke setIdentity after initSession

initSession must be invoked first, otherwise the initSession callback will not fire properly.

// login
Branch.getInstance().setIdentity("your_user_id")

// logout
Branch.getInstance().logout()
// login
[[Branch getInstance] setIdentity:@"your_user_id"];

// logout
[[Branch getInstance] logout];

Track Events

  • All events related to a customer purchasing are bucketed into a "Commerce" class of data items

  • All events related to users interacting with your in-app content are bucketed to a "Content" class of data items.

  • All events related to users progressing in your app are bucketed to a "Lifecycle" class of data items.

  • To track custom events - not found in the table below - please see Track Custom Events

  • Validate with the Branch Dashboard

Use the table below to quickly find the event you want to track.

Event Name Event Category iOS
Add To Cart Commerce Event BranchStandardEventAddToCart
Add To Wishlist Commerce Event BranchStandardEventAddToWishlist
View Cart Commerce Event BranchStandardEventViewCart
Initiate Purchase Commerce Event BranchStandardEventInitiatePurchase
Add Payment Info Commerce Event BranchStandardEventAddPaymentInfo
Purchase Commerce Event BranchStandardEventPurchase
Spend Credits Commerce Event BranchStandardEventSpendCredits
Search Content Event BranchStandardEventSearch
View Item Content Event BranchStandardEventViewItem
View Items Content Event BranchStandardEventViewItems
Rate Content Event BranchStandardEventRate
Share Content Event BranchStandardEventShare
Complete Registration Lifecycle Event BranchStandardEventCompleteRegistration
Complete Tutorial Lifecycle Event BranchStandardEventCompleteTutorial
Achieve Level Lifecycle Event BranchStandardEventAchieveLevel
Unlock Achievement Lifecycle Event BranchStandardEventUnlockAchievement

Handle Push Notifications

  • Allows you to track Branch deep links in your push notifications

  • Include the Branch push notification handler in Initialize Branch

  • Add a Branch deep link in your push notification payload

    • Replace https://example.app.link/u3fzDwyyjF with your deep link
{
  "aps": {
    "alert": "Push notification with a Branch deep link",
    "badge": "1"
  },
  "branch": "https://example.app.link/u3fzDwyyjF"
}

Handle Links in Your Own App

  • Allows you to deep link into your own from your app itself
Branch.getInstance().handleDeepLink(withNewSession: URL(string: "https://example.app.link/u3fzDwyyjF"))
[[Branch getInstance] handleDeepLinkWithNewSession:[NSURL URLWithString:@"https://example.app.link/u3fzDwyyjF"]];

Handling a new deep link in your app

Handling a new deep link in your app will clear the current session data and a new referred "open" will be attributed.

Track Apple Search Ads

  • Allows Branch to track Apple Search Ads deep linking analytics

  • Analytics from Apple's API have been slow which will make our analytics lower. Additionally, Apple's API does not send us all the data of an ad every time which will make ads tracked by us to show a generic campaign sometimes.

  • Add before initSession Initialize Branch

Branch.getInstance().delayInitToCheckForSearchAds()
[[Branch getInstance] delayInitToCheckForSearchAds];

Enable 100% Matching

  • Use the SFSafariViewController to increase the attribution matching success

  • The 100% match is a bit of a misnomer, as it is only 100% match from when a user clicks from the Safari browser. According to our analysis, clicking through Safari happens about 50-75% of the time depending on the use case. For example, clicking from Facebook, Gmail or Chrome won’t trigger a 100% match here. However, it’s still beneficial to the matching accuracy, so we recommend employing it.

  • When using a custom domain, add a branch_app_domain string key in your Info.plist with your custom domain
    to enable 100% matching.

  • By default, cookie-based matching is enabled on iOS 9 and 10 if the SafariServices.framework
    is included in an app's dependencies, and the app uses an app.link subdomain or sets the branch_app_domain
    in the Info.plist. It can be disabled with a call to the SDK.

  • Add before initSession Initialize Branch

Branch.getInstance().disableCookieBasedMatching()
[[Branch getInstance] disableCookieBasedMatching];

Enable / Disable User Tracking

If you need to comply with a user's request to not be tracked for GDPR purposes, or otherwise determine that a user should not be tracked, utilize this field to prevent Branch from sending network requests. This setting can also be enabled across all users for a particular link, or across your Branch links.

Branch.setTrackingDisabled(true)
[Branch setTrackingDisabled:YES];

You can choose to call this throughout the lifecycle of the app. Once called, network requests will not be sent from the SDKs. Link generation will continue to work, but will not contain identifying information about the user. In addition, deep linking will continue to work, but will not track analytics for the user.

Share to Email Options

  • Change the way your deep links behave when shared to email

  • Needs a Share deep link

lp.addControlParam("$email_subject", withValue: "Your Awesome Deal")
lp.addControlParam("$email_html_header", withValue: "<style>your awesome CSS</style>\nOr Dear Friend,")
lp.addControlParam("$email_html_footer", withValue: "Thanks!")
lp.addControlParam("$email_html_link_text", withValue: "Tap here")
[lp addControlParam:@"$email_subject" withValue:@"This one weird trick."];
[lp addControlParam:@"$email_html_header" withValue:@"<style>your awesome CSS</style>\nOr Dear Friend,"];
[lp addControlParam:@"$email_html_footer" withValue:@"Thanks!"];
[lp addControlParam:@"$email_html_link_text" withValue:@"Tap here"];

Share Message Dynamically

  • Change the message you share based on the source the users chooses

  • Needs a Share deep link

// import delegate
class ViewController: UITableViewController, BranchShareLinkDelegate

func branchShareLinkWillShare(_ shareLink: BranchShareLink) {
  // choose shareSheet.activityType
  shareLink.shareText = "\(shareLink.linkProperties.channel)"
}
// import delegate
@interface ViewController () <BranchShareLinkDelegate>

  - (void) branchShareLinkWillShare:(BranchShareLink*)shareLink {
  // choose shareSheet.activityType
  shareLink.shareText = [NSString stringWithFormat:@"@%", shareLink.linkProperties.channel];
}

Updated 11 days ago

iOS Advanced Features


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.