Get Started

If you're interested in an iOS video player with the SDK pre-integrated, check out the Google Media Framework.

Prerequisites

Before you begin, you'll need the following:

If you'd rather follow along with a finished IMA SDK integration, download BasicExample.zip or view it on GitHub.

Adding the SDK to the Xcode project

Streamlined, using CocoaPods (Preferred)

If you don't have CocoaPods installed on your machine, see the CocoaPods documentation. To use CocoaPods, create a Podfile in the directory containing the SampleVideoPlayer.xcodeproj directory. For the IMA SDK, the Podfile should look like this:

source 'https://github.com/CocoaPods/Specs.git'

platform :ios, '9.0'

target "SampleVideoPlayer" do # where "SampleVideoPlayer" is the name of your Xcode project
  pod 'GoogleAds-IMA-iOS-SDK', '~> 3.4'
end

With that file created, run pod install in the same directory to automatically download the IMA SDK. Once that command completes, open the .xcworkspace file in Xcode. Inside the Xcode Workspace, you'll see two projects - one for the SampleVideoPlayer, and the other for the dependencies installed by CocoaPods.

Your first ads request

  1. Import the IMA SDK
  2. To start, we're going to import the IMA framework. To do so, navigate to ViewController.m and add the following beneath your imports list:

    Objective-C

    ViewController.m
    #import "ViewController.h"
    
    @import GoogleInteractiveMediaAds;
    
    @interface ViewController ()
    ...
    

    Swift

    ViewController.swift
    import AVFoundation
    import UIKit
    
    import GoogleInteractiveMediaAds
    
    class ViewController: UIViewcontroller {
      ...
    

  3. Define a Content Playhead Tracker
  4. In order to play mid-rolls, the SDK needs to track the current position of your video content. For it to do this you'll need to create a class that implements IMAContentPlayhead. If you're using an AVPlayer, the SDK provides the IMAAVPlayerContentPlayhead class which does this for you. If you're not using AVPlayer, you'll need to implement IMAContentPlayhead on a class of your own. The below snippet shows how to set up a playhead tracker for an implementation that is using an AVPlayer.

    You'll also need to let the SDK know when your content is done playing so it can display post-rolls. This is done by calling contentComplete on the IMAAdsLoader. We do this below using AVPlayerItemDidPlayToEndTimeNotification.

    Objective-C

    ViewController.m
    #import "ViewController.h"
    
    @import GoogleInteractiveMediaAds;
    
    @interface ViewController ()
    ...
    @property(nonatomic, strong) IMAAVPlayerContentPlayhead *contentPlayhead;
    ...
    @end
    
    - (void)setUpContentPlayer {
      ...
      // Set up our content playhead and contentComplete callback.
      self.contentPlayhead = [[IMAAVPlayerContentPlayhead alloc] initWithAVPlayer:self.contentPlayer];
      [[NSNotificationCenter defaultCenter] addObserver:self
                                               selector:@selector(contentDidFinishPlaying:)
                                                   name:AVPlayerItemDidPlayToEndTimeNotification
                                                 object:self.contentPlayer.currentItem];
    }
    
    - (void)contentDidFinishPlaying:(NSNotification *)notification {
      // Make sure we don't call contentComplete as a result of an ad completing.
      if (notification.object == self.contentPlayer.currentItem) {
        // NOTE: This line will cause an error until the next step, "Request Ads".
        [self.adsLoader contentComplete];
      }
    }
    

    Swift

    ViewController.swift
    import AVFoundation
    import UIKit
    
    import GoogleInteractiveMediaAds
    
    class ViewController: UIViewController {
      ...
      var contentPlayhead: IMAAVPlayerContentPlayhead?
    
      ...
    
      func setUpContentPlayer() {
        ...
        contentPlayhead = IMAAVPlayerContentPlayhead(AVPlayer: contentPlayer)
        NSNotificationCenter.defaultCenter().addObserver(
            self,
            selector: "contentDidFinishPlaying:",
            name: AVPlayerItemDidPlayToEndTimeNotification,
            object: contentPlayer!.currentItem);
      }
    
      func contentDidFinishPlaying(notification: NSNotification) {
        // Make sure we don't call contentComplete as a result of an ad completing.
        if ((notification.object as! AVPlayerItem) == contentPlayer!.currentItem) {
          // NOTE: This line will cause an error until the next step, "Request Ads".
          adsLoader!.contentComplete()
        }
      }
    }
    

  5. Request Ads
  6. Now that you've defined your ad display container, rendering settings, and content playhead, you're ready to make an ads request. To request ads, you'll need an instance of IMAAdsLoader, an ad tag, and the ad display container you defined earlier. You'll also need to change some existing code to make sure ads get requested when the user clicks the play button.

    Objective-C

    ViewController.m
    @interface ViewController ()
    ...
    @property(nonatomic, strong) IMAAdsLoader *adsLoader;
    ...
    @end
    ...
    NSString *const kTestAppAdTagUrl =
        @"https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&"
        @"iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&"
        @"gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&"
        @"cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&correlator="
    
    - (void)viewdidLoad {
      [super viewDidLoad];
    
      self.playButton.layer.zPosition = MAXFLOAT;
    
      [self setUpContentPlayer];
      [self setupAdsLoader];
    }
    
    - (IBAction)onPlayButtonTouch:(id)sender {
      //[self.contentPlayer play];
      [self requestAds];
      self.playButton.hidden = YES;
    }
    
    - (void)setupAdsLoader {
      // Re-use this IMAAdsLoader instance for the entire lifecycle of your app.
      self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:nil];
      // NOTE: This line will cause a warning until the next step, "Get the Ads Manager".
      self.adsLoader.delegate = self;
    }
    
    - (void)requestAds {
      // Create an ad display container for ad rendering.
      IMAAdDisplayContainer *adDisplayContainer =
          [[IMAAdDisplayContainer alloc] initWithAdContainer:self.videoView companionSlots:nil];
      // Create an ad request with our ad tag, display container, and optional user context.
      IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:kTestAppAdTagUrl
                                                    adDisplayContainer:adDisplayContainer
                                                       contentPlayhead:self.contentPlayhead
                                                           userContext:nil];
      [self.adsLoader requestAdsWithRequest:request];
    }
    

    Swift

    ViewController.swift
    class ViewController: UIViewController {
      ...
      var adsLoader: IMAAdsLoader?
    
      let kTestAppAdTagUrl = "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&" +
          "iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&" +
          "gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&" +
          "cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&correlator=";
    
      ...
    
      override func viewDidLoad() {
        super.viewDidLoad()
    
        playButton.layer.zPosition = CGFloat.AX
    
        setUpContentPlayer()
        setUpAdsLoader()
      }
    
      @IBAction func onPlayButtonTouch(sender: AnyObject) {
        //contentPlayer!.play()
        requestAds()
        playButton.hidden = true
      }
    
      func setUpAdsLoader() {
        adsLoader = IMAAdsLoader(settings: nil)
        // NOTE: This line will cause an error until the next step, "Get the Ads Manager".
        adsLoader!.delegate = self
      }
    
      func requestAds() {
        // Create an ad display container for ad rendering.
        var adDisplayContainer = IMAAdDisplayContainer(adContainer: videoView, companionSlots: nil)
    
        // Create a content playhead so the SDK can track our content for VMAP and ad rules.
        createContentPlayhead()
    
        // Create an ad request with our ad tag, display container, and optional user context.
        var request = IMAAdsRequest(
            adTagUrl: kTestAppAdTagUrl,
            adDisplayContainer: adDisplayContainer,
            contentPlayhead: contentPlayhead,
            userContext: nil)
    
        adsLoader!.requestAdsWithRequest(request)
      }
    }
    

    At this point you're requesting ads and should be getting a response from the ad server, but no ads will play. To show and play ads, you'll need to work with the IMAAdsManager.

  7. Get the Ads Manager
  8. If your ads requests is successful, the SDK will create an ads manager for you, and pass it to you in the adsLoader:adsLoadedWithData method. Once you have your instance of the ads manager, you'll provide it with the ads rendering settings and content playhead you defined earlier.

    Objective-C

    ViewController.m
    @interface ViewController () <IMAAdsLoaderDelegate>
    ...
    @property(nonatomic, strong) IMAAdsManager *adsManager;
    ...
    @end
    ...
    - (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
      // Grab the instance of the IMAAdsManager and set ourselves as the delegate.
      self.adsManager = adsLoadedData.adsManager;
    
      // NOTE: This line will cause a warning until the next step, "Display Ads".
      self.adsManager.delegate = self;
    
      // Create ads rendering settings and tell the SDK to use the in-app browser.
      IMAAdsRenderingSettings *adsRenderingSettings = [[IMAAdsRenderingSettings alloc] init];
      adsRenderingSettings.webOpenerPresentingController = self;
    
      // Initialize the ads manager.
      [self.adsManager initializeWithAdsRenderingSettings:adsRenderingSettings];
    }
    
    - (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData {
      // Something went wrong loading ads. Log the error and play the content.
      NSLog(@"Error loading ads: %@", adErrorData.adError.message);
      [self.contentPlayer play];
    }
    

    Swift

    ViewController.swift
    class ViewController: UIViewController, IMAAdsLoaderDelegate {
      ...
      var adsManager: IMAAdsManager?
      ...
      func adsLoader(loader: IMAAdsLoader!, adsLoadedWithData adsLoadedData: IMAAdsLoadedData!) {
        // Grab the instance of the IMAAdsManager and set ourselves as the delegate
        adsManager = adsLoadedData.adsManager
        adsManager!.delegate = self
    
        // Create ads rendering settings and tell the SDK to use the in-app browser.
        var adsRenderingSettings = IMAAdsRenderingSettings()
        adsRenderingSettings.webOpenerPresentingController = self
    
        // Initialize the ads manager.
        adsManager!.initializeWithAdsRenderingSettings(adsRenderingSettings)
      }
    
      func adsLoader(loader: IMAAdsLoader!, failedWithErrorData adErrorData: IMAAdLoadingErrorData!) {
        NSLog("Error loading ads: \(adErrorData.adError.message)")
        contentPlayer!.play()
      }
    }
    

  9. Display Ads
  10. Now that you have an instance of the AdsManager, you can display ads. To do this you'll need to implement the AdsManagerDelegate methods as follows:

    Objective-C

    ViewController.m
    @interface ViewController ()  <IMAAdsLoaderDelegate, IMAAdsManagerDelegate>
    ...
    @end
    ...
    - (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event {
      if (event.type == kIMAAdEvent_LOADED) {
        // When the SDK notifies us that ads have been loaded, play them.
        [adsManager start];
      }
    }
    
    - (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdError:(IMAAdError *)error {
      // Something went wrong with the ads manager after ads were loaded. Log the error and play the
      // content.
      NSLog(@"AdsManager error: %@", error.message);
      [self.contentPlayer play];
    }
    
    - (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager {
      // The SDK is going to play ads, so pause the content.
      [self.contentPlayer pause];
    }
    
    - (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager {
      // The SDK is done playing ads (at least for now), so resume the content.
      [self.contentPlayer play];
    }
    

    Swift

    ViewController.swift
    class ViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate {
      ...
      func adsManager(adsManager: IMAAdsManager!, didReceiveAdEvent event: IMAAdEvent!) {
        if (event.type == IMAAdEventType.LOADED) {
          // When the SDK notifies us that ads have been loaded, play them.
          adsManager.start()
        }
      }
    
      func adsManager(adsManager: IMAAdsManager!, didReceiveAdError error: IMAAdError!) {
        // Something went wrong with the ads manager after ads were loaded. Log the
        // error and play the content.
        NSLog("AdsManager error: \(error.message)")
        contentPlayer!.play()
      }
    
      func adsManagerDidRequestContentPause(adsManager: IMAAdsManager!) {
        // The SDK is going to play ads, so pause the content.
        contentPlayer!.pause()
      }
    
      func adsManagerDidRequestContentResume(adsManager: IMAAdsManager!) {
        // The SDK is done playing ads (at least for now), so resume the content.
        contentPlayer!.play()
      }
    }
    

    That's it! You're now requesting and displaying your first ads. For more info on fine-tuning your implementation, check out advanced topics.

    Full source

    Objective-C

    Viewcontroller.m
    #import "ViewController.h"
    
    @import AVFoundation;
    @import GoogleInteractiveMediaAds;
    
    @interface ViewController () <IMAAdsLoaderDelegate, IMAAdsManagerDelegate>
    
    /// Content video player.
    @property(nonatomic, strong) AVPlayer *contentPlayer;
    
    /// Play button.
    @property(nonatomic, weak) IBOutlet UIButton *playButton;
    
    /// UIView in which we will render our AVPlayer for content.
    @property(nonatomic, weak) IBOutlet UIView *videoView;
    
    // SDK
    /// Entry point for the SDK. Used to make ad requests.
    @property(nonatomic, strong) IMAAdsLoader *adsLoader;
    
    /// Playhead used by the SDK to track content video progress and insert mid-rolls.
    @property(nonatomic, strong) IMAAVPlayerContentPlayhead *contentPlayhead;
    
    /// Main point of interaction with the SDK. Created by the SDK as the result of an ad request.
    @property(nonatomic, strong) IMAAdsManager *adsManager;
    
    @end
    
    @implementation ViewController
    
    // The content URL to play.
    NSString *const kTestAppContentUrl_MP4 = @"http://rmcdn.2mdn.net/Demo/html5/output.mp4";
    
    // Ad tag
    NSString *const kTestAppAdTagUrl = @"https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&"
        @"iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&gdfp_req=1&env=vp&"
        @"output=vast&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&"
        @"correlator=";
    
    - (void)viewDidLoad {
      [super viewDidLoad];
    
      self.playButton.layer.zPosition = MAXFLOAT;
    
      [self setupAdsLoader];
      [self setUpContentPlayer];
    }
    
    - (IBAction)onPlayButtonTouch:(id)sender {
      [self requestAds];
      self.playButton.hidden = YES;
    }
    
    #pragma mark Content Player Setup
    
    - (void)setUpContentPlayer {
      // Load AVPlayer with path to our content.
      NSURL *contentURL = [NSURL URLWithString:kTestAppContentUrl_MP4];
      self.contentPlayer = [AVPlayer playerWithURL:contentURL];
    
      // Create a player layer for the player.
      AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.contentPlayer];
    
      // Size, position, and display the AVPlayer.
      playerLayer.frame = self.videoView.layer.bounds;
      [self.videoView.layer addSublayer:playerLayer];
    
      // Set up our content playhead and contentComplete callback.
      self.contentPlayhead = [[IMAAVPlayerContentPlayhead alloc] initWithAVPlayer:self.contentPlayer];
      [[NSNotificationCenter defaultCenter] addObserver:self
                                               selector:@selector(contentDidFinishPlaying:)
                                                   name:AVPlayerItemDidPlayToEndTimeNotification
                                                 object:self.contentPlayer.currentItem];
    }
    
    #pragma mark SDK Setup
    
    - (void)setupAdsLoader {
      self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:nil];
      self.adsLoader.delegate = self;
    }
    
    - (void)requestAds {
      // Create an ad display container for ad rendering.
      IMAAdDisplayContainer *adDisplayContainer =
          [[IMAAdDisplayContainer alloc] initWithAdContainer:self.videoView companionSlots:nil];
      // Create an ad request with our ad tag, display container, and optional user context.
      IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:kTestAppAdTagUrl
                                                    adDisplayContainer:adDisplayContainer
                                                       contentPlayhead:self.contentPlayhead
                                                           userContext:nil];
      [self.adsLoader requestAdsWithRequest:request];
    }
    
    - (void)contentDidFinishPlaying:(NSNotification *)notification {
      // Make sure we don't call contentComplete as a result of an ad completing.
      if (notification.object == self.contentPlayer.currentItem) {
        [self.adsLoader contentComplete];
      }
    }
    
    #pragma mark AdsLoader Delegates
    
    - (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
      // Grab the instance of the IMAAdsManager and set ourselves as the delegate.
      self.adsManager = adsLoadedData.adsManager;
      self.adsManager.delegate = self;
      // Create ads rendering settings to tell the SDK to use the in-app browser.
      IMAAdsRenderingSettings *adsRenderingSettings = [[IMAAdsRenderingSettings alloc] init];
      adsRenderingSettings.webOpenerPresentingController = self;
      // Initialize the ads manager.
      [self.adsManager initializeWithAdsRenderingSettings:adsRenderingSettings];
    }
    
    - (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData {
      // Something went wrong loading ads. Log the error and play the content.
      NSLog(@"Error loading ads: %@", adErrorData.adError.message);
      [self.contentPlayer play];
    }
    
    #pragma mark AdsManager Delegates
    
    - (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event {
      // When the SDK notified us that ads have been loaded, play them.
      if (event.type == kIMAAdEvent_LOADED) {
        [adsManager start];
      }
    }
    
    - (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdError:(IMAAdError *)error {
      // Something went wrong with the ads manager after ads were loaded. Log the error and play the
      // content.
      NSLog(@"AdsManager error: %@", error.message);
      [self.contentPlayer play];
    }
    
    - (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager {
      // The SDK is going to play ads, so pause the content.
      [self.contentPlayer pause];
    }
    
    - (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager {
      // The SDK is done playing ads (at least for now), so resume the content.
      [self.contentPlayer play];
    }
    
    @end
    

    Swift

    ViewController.swift
    import AVFoundation
    import GoogleInteractiveMediaAds
    import UIKit
    
    class ViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate {
    
      static let kTestAppContentUrl_MP4 = "http://rmcdn.2mdn.net/Demo/html5/output.mp4"
    
      @IBOutlet weak var playButton: UIButton!
      @IBOutlet weak var videoView: UIView!
      var contentPlayer: AVPlayer?
      var playerLayer: AVPlayerLayer?
    
      var contentPlayhead: IMAAVPlayerContentPlayhead?
      var adsLoader: IMAAdsLoader!
      var adsManager: IMAAdsManager!
    
      static let kTestAppAdTagUrl =
          "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&" +
          "iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&gdfp_req=1&env=vp&" +
          "output=vast&unviewed_position_start=1&" +
          "cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&correlator=";
    
      override func viewDidLoad() {
        super.viewDidLoad()
    
        playButton.layer.zPosition = CGFloat.greatestFiniteMagnitude
    
        setUpContentPlayer()
        setUpAdsLoader()
      }
    
      override func viewDidAppear(_ animated: Bool) {
        playerLayer?.frame = self.videoView.layer.bounds
      }
    
      @IBAction func onPlayButtonTouch(_ sender: AnyObject) {
        //contentPlayer.play()
        requestAds()
        playButton.isHidden = true
      }
    
      func setUpContentPlayer() {
        // Load AVPlayer with path to our content.
        guard let contentURL = URL(string: ViewController.kTestAppContentUrl_MP4) else {
          print("ERROR: please use a valid URL for the content URL")
          return
        }
        contentPlayer = AVPlayer(url: contentURL)
    
        // Create a player layer for the player.
        playerLayer = AVPlayerLayer(player: contentPlayer)
    
        // Size, position, and display the AVPlayer.
        playerLayer?.frame = videoView.layer.bounds
        videoView.layer.addSublayer(playerLayer!)
    
        // Set up our content playhead and contentComplete callback.
        contentPlayhead = IMAAVPlayerContentPlayhead(avPlayer: contentPlayer)
        NotificationCenter.default.addObserver(
          self,
          selector: #selector(ViewController.contentDidFinishPlaying(_:)),
          name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
          object: contentPlayer?.currentItem);
      }
    
      func contentDidFinishPlaying(_ notification: Notification) {
        // Make sure we don't call contentComplete as a result of an ad completing.
        if (notification.object as! AVPlayerItem) == contentPlayer?.currentItem {
          adsLoader.contentComplete()
        }
      }
    
      func setUpAdsLoader() {
        adsLoader = IMAAdsLoader(settings: nil)
        adsLoader.delegate = self
      }
    
      func requestAds() {
        // Create ad display container for ad rendering.
        let adDisplayContainer = IMAAdDisplayContainer(adContainer: videoView, companionSlots: nil)
        // Create an ad request with our ad tag, display container, and optional user context.
        let request = IMAAdsRequest(
            adTagUrl: ViewController.kTestAppAdTagUrl,
            adDisplayContainer: adDisplayContainer,
            contentPlayhead: contentPlayhead,
            userContext: nil)
    
        adsLoader.requestAds(with: request)
      }
    
      // MARK: - IMAAdsLoaderDelegate
    
      func adsLoader(_ loader: IMAAdsLoader!, adsLoadedWith adsLoadedData: IMAAdsLoadedData!) {
        // Grab the instance of the IMAAdsManager and set ourselves as the delegate.
        adsManager = adsLoadedData.adsManager
        adsManager.delegate = self
    
        // Create ads rendering settings and tell the SDK to use the in-app browser.
        let adsRenderingSettings = IMAAdsRenderingSettings()
        adsRenderingSettings.webOpenerPresentingController = self
    
        // Initialize the ads manager.
        adsManager.initialize(with: adsRenderingSettings)
      }
    
      func adsLoader(_ loader: IMAAdsLoader!, failedWith adErrorData: IMAAdLoadingErrorData!) {
        print("Error loading ads: \(adErrorData.adError.message)")
        contentPlayer?.play()
      }
    
      // MARK: - IMAAdsManagerDelegate
    
      func adsManager(_ adsManager: IMAAdsManager!, didReceive event: IMAAdEvent!) {
        if event.type == IMAAdEventType.LOADED {
          // When the SDK notifies us that ads have been loaded, play them.
          adsManager.start()
        }
      }
    
      func adsManager(_ adsManager: IMAAdsManager!, didReceive error: IMAAdError!) {
        // Something went wrong with the ads manager after ads were loaded. Log the error and play the
        // content.
        print("AdsManager error: \(error.message)")
        contentPlayer?.play()
      }
    
      func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager!) {
        // The SDK is going to play ads, so pause the content.
        contentPlayer?.pause()
      }
    
      func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager!) {
        // The SDK is done playing ads (at least for now), so resume the content.
        contentPlayer?.play()
      }
    }
    
    

Send feedback about...

IMA SDK for iOS
Need help? Visit our support page.