Search specific term/phrase surrounded by double quotes. e.g. “deep linking”
Exclude records that contain a specific term prefixed with a minus. e.g. Android -Firebase

tvOS Basic Integration

👍

SDK Stats

Open Source Github Repo: https://github.com/BranchMetrics/ios-branch-deep-linking

SDK Size: ~220kb (with all Branch features enabled)

Speed: Median 80ms to 250ms

Minimum XCode Version: 12+

Minimum OS version: iOS 9+

📘

iOS 14 Implementation

In order to give you full control over the user experience, the Branch SDK will not trigger the IDFA permission modal.

However, we will still collect and use IDFAs when available if you do choose to trigger the modal.

LEARN MORE

Configure Branch

tvOS uses the same Universal Links as iOS. It does not support redirect to URI scheme or web.

1590

Configure Bundle Identifier

1912

Branch assumes you use the same bundle id for all Apple platforms. If you use different bundle ids, you can set the bundle id to a consistent value when initializing the Branch SDK.

Configure Associated Domains

  • In the Xcode Signing & Capabilities tab, add Associated Domains
  • Add your link domains from your Branch Dashboard
  • -alternate is needed for Universal Linking with the Web SDK inside your Website
  • test- is needed if you need use a test key
  • If you use a custom link domain, you will need to include your old link domain, your -alternate link domain, and your new link domain
1918

Configure Info.plist

  • Add Branch Dashboard values

    • Add branch_universal_link_domains with your live key domain
    • Add branch_key with your current Branch key
    • Add your URI scheme as URL Types -> Item 0 -> URL Schemes
1716

Confirm App Prefix

1984

Install Branch

Option 1

CocoaPods

platform :tvos, '9.0'

target 'APP_NAME' do
  # if swift
  use_frameworks!

  pod 'Branch'
end
pod install && pod update

Option 2

🚧

Carthage 0.36.x does not include support for xcframeworks

Carthage support for xcframeworks is not included in the 0.36.x release. You can install Carthage from source to gain access to the --use-xcframeworks option.

Carthage install instructions

Carthage

Branch iOS SDK now supports xcframework and requires the --use-xcframeworks option.

github "BranchMetrics/ios-branch-deep-linking"
  • Import the Branch.xcframework into Linked Frameworks
  • Import AdSupport and CoreServices into Linked Frameworks

Option 3

From the 0.37.0 release, the Branch iOS SDK github releases page includes a prebuilt xcframework in Branch.zip and a checksum.

  • Drag and drop Branch.xcframework into *Embedded Binaries (select Copy items if needed**)
  • Import AdSupport and CoreServices, into Linked Frameworks
2092

Initialize Branch

In your app's AppDelegate

import UIKit
import Branch

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  // if you are using the TEST key
  Branch.setUseTestBranchKey(true)
  // listener for Branch Deep Link data
  Branch.getInstance().initSession(launchOptions: launchOptions, andRegisterDeepLinkHandler: { (params, error) in
    // do stuff with deep link data (nav to page, display content, etc)
    print(params as? [String: AnyObject] ?? {})
  }
  return true
}

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
  Branch.getInstance().application(app, open: url, options: options)
  return true
}

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
  // handler for Universal Links
  Branch.getInstance().continue(userActivity)
  return true
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
  // handler for Push Notifications
  Branch.getInstance().handlePushNotification(userInfo)
}

App to App linking on tvOS

tvOS does not have a web browser or a web view. We workaround this limitation by App to App programmatic linking.

For this section, "ad partner app" refers to the tvOS app that wishes to link your Branch enabled tvOS app, the "target app". The ad partner app does not need to be Branch enabled.

App to App linking is implemented in the ad partner app.

  • Add the AdSupport framework. This is used to obtain the device IDFA.
  • Enable the ad partner app to query for your tvOS app by adding your URI scheme to the Info.plist. See canOpenURL
2782

The following code demonstrates how to link from the ad partner app to the target app.

  • The target app's Branch Link has the device IDFA appended to it as a query parameter.
  • We query for the target app using canOpenURL. Note, canOpenURL is checking the URI scheme, while Branch Links are Universal Links.
  • If we detect the app, we attempt to open it with the Branch Link. If we do not detect the app or we fail to open it with the Branch Link, we fallback to sending a click to the Branch server then opening the app store.
// This example opens the target app using a Branch Link.  This does get Branch parameters and deferred deeplink data.
    @IBAction func testBranchLink() {
        
        // Since tvOS only supports app to app linking, we simply pass the advertising identifier as a query parameter
        // Also added the adpartner parameter just to indicate where this came from, not strictly necessary
        let branchLink = "https://bnctestbed.app.link/cCWdYYokQ6?$os=tv_os&$idfa=" + self.checkIdfa()
        
        guard let url = URL(string: branchLink) else { return }
        guard let uriScheme = URL(string: "branchtest://") else { return }
        
        self.openURL(url: url, uriScheme: uriScheme)
    }
    
    func checkIdfa() -> String {
        return ASIdentifierManager.shared().advertisingIdentifier.uuidString
    }
    
    // We assume the uri scheme is for the same app as the universal link url
    func openURL(url:URL, uriScheme:URL) {
        
        // canOpenURL can only check URI schemes listed in the Info.plist.  It cannot check Universal Links.
        // https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl
        if (UIApplication.shared.canOpenURL(uriScheme)) {
            if #available(tvOS 10.0, *) {
                UIApplication.shared.open(url, options: [:]) { (success) in
                    if (success == false) {
                        self.clickBranchLink(url: url)
                    }
                }
            } else {
                let success = UIApplication.shared.openURL(url)
                if (success == false) {
                    self.clickBranchLink(url: url)
                }
            }
            
        } else {
            self.clickBranchLink(url: url)
        }
    }
    
    func clickBranchLink(url:URL) {
        URLSession.shared.dataTask(with: url) { (data, response, error) in
            DispatchQueue.main.async {
                self.openAppStore()
            }
        }.resume()
    }
    
    // directly open the app store if we're unable to detect the app
    func openAppStore() {
        guard let url = URL(string:"https://apps.apple.com/us/app/branch-monster-factory/id917737838?mt=8") else { return }
        
        if #available(tvOS 10.0, *) {
            UIApplication.shared.open(url, options: [:]) { (success) in
                
            }
        } else {
            UIApplication.shared.openURL(url)
        }
    }