# Ads

## Google IMA

Google IMA SDKs make it easy to integrate multimedia ads into your websites and apps. IMA SDKs can request ads from any VAST-compliant 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.

CastlabsIMA integrates the Google SDK into our player, handles automatically the required callbacks, and simplifies the public API.

The Google IMA SDK provides the tools to integrate and manage video ads in your app. PRESTOplay SDK simplifies displaying ads by providing an interface to the Google IMA SDK, making it easy to incorporate and control ads in your application.

### Integrate

Include the `GoogleAds-IMA-iOS-SDK` library in your project. Here is an example using CocoaPods:

    pod 'GoogleAds-IMA-iOS-SDK'

Register the IMA plugin to PRESTOplay SDK:

    import PRESTOplay
    import CastlabsIMA

    ...

    PRESTOplaySDK.shared.setup("LICENSE", [IMAPlugin()])

### Scheduling Ads

In your view controller, you can schedule ads as follows:

    override func viewDidAppear(_ animated: Bool) {
        ...
        let adsSettings = AdsSettings(enableDebugMode: true)
        let ads = PRESTOplaySDK.shared.ads(for: player, settings: adsSettings)
        let url = URL(string: "https://players.castlabs.com/ads/vmap?ad=1,start&ad=00:01:15&ad=1,end")!
        ads?.requestAds(withUrl: url, onView: view, viewController: self)
    }

Note: Since the Google IMA SDK requires the ad container to be in the view hierarchy, the `requestAds()` method should be called within the `viewDidAppear()` event.

Please check our `examples/IMADemo` for complete implementation.

### Advanced IMA settings

`AdsSettings` exposes additional IMA behavior controls:

    let adsSettings = AdsSettings(
        ppid: "publisher-user-id",
        language: "en-US",
        maxRedirects: 8,
        featureFlags: [:],
        enableBackgroundPlayback: true,
        autoPlayAdBreaks: true,
        disableNowPlayingInfo: false,
        playerType: "MyPlayer",
        playerVersion: "1.0.0",
        sessionID: UUID().uuidString,
        sameAppKeyEnabled: true,
        waitForAdResponse: true,
        enableDebugMode: false
    )
    let ads = PRESTOplaySDK.shared.ads(for: player, settings: adsSettings)

This covers advanced ad behavior such as background ad playback, ad-break autoplay, redirect limits, localization, and ad-session identification.

### Ads events

Clients can receive ad events through the `AdsAPI.onAdsState` closure.

    var player = PRESTOplaySDK.shared.player()
    var ads = PRESTOplaySDK.shared.ads(for: player, settings: AdsSettings(enableDebugMode: true))
    ads?.onAdsState = { state in
        switch state.adsEvent?.type {
        case .started:
            print("Ad started")
        case .complete:
            print("Ad complete")
        case .allAdsCompleted:
            print("All Ads complete")
        default:
            print("\(state.adsEvent?.type)")
        }
    }

### Ad errors

Ad-related errors are reported through the `PRESTOplaySDK.shared.onError` closure. These errors are non-fatal and have the following characteristics:

- Error Type: `ads_error`
- Severity: `warning`

Additional contextual information is provided through the data field of the error object. For example, when using IMA, the following fields may be included:

- errorType: The type of error that occurred during ad loading or ad playing.
- errorCode: The error code for obtaining more specific information about the error.

The errorType may have one of the following values:

- adLoadingFailed – An error occurred while loading the ads.
- adPlayingFailed – An error occurred while playing the ads.
- adUnknownErrorType – An unexpected error occurred while loading or playing the ads.

    //...

    PRESTOplaySDK.shared.onError = { [weak self] _, error in
        guard let self else { return }
        if error.type == .ads_error {
            // handle ad errors
            if error.data.keys.contains("errorType"), error.data["errorType"] == "adLoadingFailed" {
                // ...
            }
        }
    }

### More information

iOS targets: https://developers.google.com/interactive-media-ads/docs/sdks/ios/download

tvOS targets: https://developers.google.com/interactive-media-ads/docs/sdks/tvos/download

More details on how to start with Google IMA can be found here:

https://developers.google.com/interactive-media-ads/docs/sdks/ios/

https://developers.google.com/interactive-media-ads/docs/sdks/tvos/