Select platform: [HTML5](https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/get-started.md.txt "View this page for the HTML5 platform docs.") [Android](https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/get-started.md.txt "View this page for the Android platform docs.") [iOS](https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/get-started.md.txt "View this page for the iOS platform docs.") [tvOS](https://developers.google.com/interactive-media-ads/docs/sdks/tvos/client-side/get-started.md.txt "View this page for the tvOS platform docs.")

<br />


IMA SDKs make it easy to integrate multimedia ads into your websites and apps. IMA SDKs can
request ads from any
[VAST-compliant](https://www.iab.com/guidelines/digital-video-ad-serving-template-vast/) ad server and manage ad playback in your apps. With IMA client-side SDKs,
you maintain control of content video playback, while the SDK handles ad playback. Ads play in a
separate video player positioned on top of the app's content video player.

<br />

This guide demonstrates how to integrate the IMA SDK into a video player
app. To view or follow along with a completed sample
integration, download the
[BasicExample](https://github.com/googleads/googleads-ima-ios) from
GitHub.


**Note:** For information on integrating with other platforms, or on using the IMA DAI SDKs, see [Interactive Media Ads SDKs](https://developers.google.com/interactive-media-ads).

<br />

## IMA client-side overview

Implementing IMA client-side involves four main SDK components, which this guide
demonstrates:

- `

  IMAAdDisplayContainer`: A container object that specifies where IMA renders ad UI elements and measures viewability, including [Active View](https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/viewability.md.txt) and [Open Measurement](https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/omsdk.md.txt).
- `
  IMAAdsLoader`: An object that requests ads and handles events from ads request responses. You should only instantiate one ads loader, which can be reused throughout the life of the application.
- `
  IMAAdsRequest`: An object that defines an ads request. Ads requests specify the URL for the VAST ad tag, as well as additional parameters, such as ad dimensions.
- `
  IMAAdsManager`: An object that contains the response to the ads request, controls ad playback, and listens for ad events fired by the SDK.

## Prerequisites

Before you begin, you need the following:

- Xcode 13 or later
- Method for installing the IMA SDK:
  - [Swift Package Manager](https://docs.swift.org/swiftpm/documentation/packagemanagerdocs/) (preferred)
  - A downloaded copy of [IMA SDK for iOS](https://developers.google.com/interactive-media-ads/docs/sdks/ios/dai/download)

## 1. Create a new Xcode project

In Xcode, create a new iOS project using Objective-C or Swift. Use
**BasicExample** as the project name.

## 2. Add the IMA SDK to the Xcode project

To install IMA SDK, choose a preferred method.

### Recommended: Install the SDK using Swift Package Manager

The Interactive Media Ads SDK supports [Swift Package
Manager](https://swift.org/package-manager/) starting in version 3.18.4. To import
the Swift package, complete the following steps:

1. In Xcode, install the IMA SDK Swift Package by navigating to
   **File \> Add Package Dependencies...**.

2. In the prompt, search for the IMA iOS SDK Swift Package GitHub repository:
   `swift-package-manager-google-interactive-media-ads-ios`.

3. Select the version of the IMA SDK Swift Package you want to use.
   For new projects, we recommend using the **Up to Next Major Version**.

Once you're finished, Xcode resolves your package dependencies and
downloads them in the background. For more details on how to add package
dependencies, see
[Apple's article](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app).

### Manually download and install the SDK

If you don't want to use Swift Package Manager, download and manually add
IMA SDK to your project.

#### Show/hide instructions

1. From the [iOS
   IMA Download page](https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/download), download and extract the latest version of the iOS IMA SDK.
2. Open **BasicExample.xcodeproj**.
3. In the left pane, click the project name.  
   ![Image showing where to click the project name in the left pane of Xcode](https://developers.google.com/static/interactive-media-ads/images/tvos-2-3-click-project-name.png)
4. In the center pane, click **Build Phases** .  
   ![Image showing where to click Build Phases in the center pane of Xcode](https://developers.google.com/static/interactive-media-ads/images/tvos-2-4-build-phases.png)
5. Expand the **Link Binary With Libraries** section.
6. At the bottom of the libraries list, click the plus icon **\[+\]**.
7. Click **Add Other**.
8. In the directory where you extracted the downloaded SDK, select **GoogleInteractiveMediaAds.framework** and click **Open**.
9. At the bottom of the libraries list, click the plus icon **\[+\]** again.
10. In the **Status** column, verify that `GoogleInteractiveMediaAds.framework` is set to `Required`.
11. Include the `-ObjC` linker flag in your build settings. For more information, see [Apple QA1490](https://developer.apple.com/library/content/qa/qa1490/_index.html).

## 3. Create a video player

First, implement a video player. Initially, this player does not use the
IMA SDK and doesn't contain any method to trigger playback.

### Objective-C

Import the player dependencies:

```objective-c
#import "ViewController.h"

@import AVFoundation;
```

Set up the player variables:

```objective-c
@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;
```

Initiate the video player when the view loads:

```objective-c
@implementation ViewController

// The content URL to play.
NSString *const kTestAppContentUrl_MP4 =
    @"https://storage.googleapis.com/gvabox/media/samples/stock.mp4";

// Ad tag
NSString *const kTestAppAdTagUrl = @"https://pubads.g.doubleclick.net/gampad/ads?"
  @"iu=/21775744923/external/single_ad_samples&sz=640x480&cust_params=sample_ct%3Dlinear&"
  @"ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&"
  @"correlator=";

- (void)viewDidLoad {
  [super viewDidLoad];

  self.playButton.layer.zPosition = MAXFLOAT;

  [self setupAdsLoader];
  [self setUpContentPlayer];
}

#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];
}

- (IBAction)onPlayButtonTouch:(id)sender {
  [self requestAds];
  self.playButton.hidden = YES;
}
```

### Swift

Import the player dependencies:

```swift
import AVFoundation
```

Set up the player variables:

```swift
class PlayerContainerViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate {
  static let contentURL = URL(
    string: "https://storage.googleapis.com/gvabox/media/samples/stock.mp4")!

  private var contentPlayer = AVPlayer(url: PlayerContainerViewController.contentURL)

  private lazy var playerLayer: AVPlayerLayer = {
    AVPlayerLayer(player: contentPlayer)
  }()
```

Initiate the video player when the view loads:

```swift
private lazy var videoView: UIView = {
  let videoView = UIView()
  videoView.translatesAutoresizingMaskIntoConstraints = false
  view.addSubview(videoView)

  NSLayoutConstraint.activate([
    videoView.bottomAnchor.constraint(
      equalTo: view.safeAreaLayoutGuide.bottomAnchor),
    videoView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
    videoView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
    videoView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
  ])
  return videoView
}()

// MARK: - View controller lifecycle methods

override func viewDidLoad() {
  super.viewDidLoad()

  videoView.layer.addSublayer(playerLayer)
  adsLoader.delegate = self

  NotificationCenter.default.addObserver(
    self,
    selector: #selector(contentDidFinishPlaying(_:)),
    name: .AVPlayerItemDidPlayToEndTime,
    object: contentPlayer.currentItem)
}

override func viewDidAppear(_ animated: Bool) {
  super.viewDidAppear(animated)
  playerLayer.frame = videoView.layer.bounds
}

override func viewWillTransition(
  to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator
) {
  coordinator.animate { _ in
    // do nothing
  } completion: { _ in
    self.playerLayer.frame = self.videoView.layer.bounds
  }
}

// MARK: - Public methods

func playButtonPressed() {
  requestAds()
}
```

## 4. Import the IMA SDK

To import the IMA SDK, do the following:

### Objective-C

1. Import the IMA SDK:

   ```objective-c
   @import GoogleInteractiveMediaAds;
   ```
2. Create variables for the `IMAAdsLoader`, `IMAAVPlayerContentPlayhead`, and
   `IMAAdsManager` classes used in the app:

   ```objective-c
   // 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;
   ```

### Swift

1. Import the IMA SDK:

   ```swift
   import GoogleInteractiveMediaAds

   ```
2. Create variables for the `IMAAdsLoader`, `IMAAVPlayerContentPlayhead`, and
   `IMAAdsManager` classes used in the app:

   ```swift
   static let adTagURLString =
     "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/"
     + "single_ad_samples&sz=640x480&cust_params=sample_ct%3Dlinear&ciu_szs=300x250%2C728x90&"
     + "gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&correlator="

   private let adsLoader = IMAAdsLoader()
   private var adsManager: IMAAdsManager?

   private lazy var contentPlayhead: IMAAVPlayerContentPlayhead = {
     IMAAVPlayerContentPlayhead(avPlayer: contentPlayer)
   }()
   ```

## 5. Implement content playhead tracker and end-of-stream observer

In order to play mid-roll ads, the IMA SDK needs to track the current position
of your video content. To do this, create a class that implements
`IMAContentPlayhead`. If you're using an `AVPlayer`, as shown in this example,
the SDK provides the `IMAAVPlayerContentPlayhead` class which does this for you.
If you're not using `AVPlayer`, you need to implement `IMAContentPlayhead` on
a class of your own.

You also need to let the SDK know when your content is done playing so it can
display post-roll ads. Do this by calling the
[`contentComplete`](https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Classes/IMAAdsLoader.md.txt#-contentcomplete)
method on the IMAAdsLoader, using `AVPlayerItemDidPlayToEndTimeNotification`.

### Objective-C

Create the `IMAAVPlayerContentPlayhead` instance in the player setup:

```objective-c
// 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];
```

Create the `contentDidFinishPlaying()` method to call
`IMAAdsLoader.contentComplete()` when the content finishes playing:

```objective-c
- (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];
  }
}
```

### Swift

Create the content ended observer in the player setup:

```swift
NotificationCenter.default.addObserver(
  self,
  selector: #selector(contentDidFinishPlaying(_:)),
  name: .AVPlayerItemDidPlayToEndTime,
  object: contentPlayer.currentItem)
```

Create the `contentDidFinishPlaying()` method to call
`IMAAdsLoader.contentComplete()` when the content finishes playing:

```swift
@objc 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()
  }
}
```

## 6. Initialize the ads loader and make an ads request

In order to request a set of ads, you need to create an `IMAAdsLoader` instance.
This loader processes `IMAAdsRequest` objects associated with a
specified ad tag URL.

As a best practice, only maintain one instance of `IMAAdsLoader` for the entire
lifecycle of your app. To make additional ad requests, create a new
`IMAAdsRequest` object, but re-use the same `IMAAdsLoader`. For more
information, see the [IMA SDK FAQ](https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/faq.md.txt#8).

### Objective-C

```objective-c
- (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
                                          viewController:self
                                          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

```swift
private func requestAds() {
  // Create ad display container for ad rendering.
  let adDisplayContainer = IMAAdDisplayContainer(
    adContainer: videoView, viewController: self, companionSlots: nil)
  // Create an ad request with our ad tag, display container, and optional user context.
  let request = IMAAdsRequest(
    adTagUrl: PlayerContainerViewController.adTagURLString,
    adDisplayContainer: adDisplayContainer,
    contentPlayhead: contentPlayhead,
    userContext: nil)

  adsLoader.requestAds(with: request)
}
```

## 7. Set up an ads loader delegate

On a successful load event, the `IMAAdsLoader` calls the
[`adsLoadedWithData`](https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Protocols/IMAAdsLoaderDelegate.md.txt#-adsloader:adsloadedwithdata:)
method of its assigned delegate, passing it an instance of `IMAAdsManager`. You
can then initialize the ads manager, which loads the individual ads, as defined
by the response to the ad tag URL.

In addition, be sure to handle any errors that may occur during the loading
process. If ads don't load, make sure that media playback continues, without
ads, so as to not interfere with the user's experience.

### Objective-C

```objective-c
- (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.linkOpenerPresentingController = 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

```swift
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.linkOpenerPresentingController = self

  // Initialize the ads manager.
  adsManager?.initialize(with: adsRenderingSettings)
}

func adsLoader(_ loader: IMAAdsLoader, failedWith adErrorData: IMAAdLoadingErrorData) {
  if let message = adErrorData.adError.message {
    print("Error loading ads: \(message)")
  }
  contentPlayer.play()
}
```

## 8. Set up an ads manager delegate

Lastly, to manage events and state changes, the ads manager needs a delegate of
its own. The `IMAAdManagerDelegate` has methods to handle ad events and errors,
as well as methods to trigger play and pause on your video content.

### Start playback

Listen for the `LOADED` event to start playback of content and ads. For more
details, see
[`didReceiveAdEvent`](https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Protocols/IMAAdsManagerDelegate.md.txt#-adsmanager:didreceiveadevent:).

### Objective-C

```objective-c
- (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];
  }
}
```

### Swift

```swift
func adsManager(_ adsManager: IMAAdsManager, didReceive event: IMAAdEvent) {
  // When the SDK notifies us the ads have been loaded, play them.
  if event.type == IMAAdEventType.LOADED {
    adsManager.start()
  }
}
```

### Handle errors

Add a handler for ad errors as well. If an error occurs, like in the previous
step, resume content playback.

### Objective-C

```objective-c
- (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];
}
```

### Swift

```swift
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.
  if let message = error.message {
    print("AdsManager error: \(message)")
  }
  contentPlayer.play()
}
```

### Listen for play and pause events

The last two delegate methods you need to implement trigger play and
pause events on the underlying video content when the IMA SDK requests them.
Triggering pause and play when requested prevents the user from missing portions
of the video content when ads display.

### Objective-C

```objective-c
- (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

```swift
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 ads with the IMA SDK. To learn
about additional SDK features, see the other guides or the
[samples on GitHub](https://github.com/googleads/googleads-ima-ios).

## Next Steps

To maximize ad revenue on the iOS platform, [request App Transparency and Tracking permission to use IDFA](https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/ios14.md.txt).