# Client-side ad insertion (CSAI) for tvOS When you use the player in your iOS or tvOS applications, you can incorporate client-side advertisements to monetize content and engage your viewers. The Apple SDK supports IMA3-based Video Ad Serving Template (VAST) and Video Multiple Ad Playlist (VMAP) ad integrations. It also accommodates popular third-party software-building tools like Google's Interactive Media Ads (IMA) SDK. With these technologies, you can customize your viewer's ad experiences and manage ad schedules and breaks within the player. For more information related to listening to ad events, managing media playback, and handling advertising errors, see the following pages: * [Listen for events](/docs/wowza-flowplayer/apple-sdk/listen-for-events/) * [Manage media playback](/docs/wowza-flowplayer/apple-sdk/manage-media-playback/) * [Handle errors](/docs/wowza-flowplayer/apple-sdk/handle-errors/) ## Before you start To configure advertisements for use with the player in your iOS or tvOS application, you must meet the following requirements: * Make sure to download Google IMA SDK iOS 3.20.0 (exact version) and Google IMA SDK tvOS 4.11.1 (exact version) depending on your project. You need this dependency to integrate multimedia ads into the player and your application. * If you're configuring ads with Wowza Video platform media, make sure you have access to Wowza Video to complete the advertising configuration. You must also generate a player token in Wowza Video and [set up the player](/docs/wowza-flowplayer/apple-sdk/configure-your-application/#set-an-access-token) to use this token. ## Configure ads with Wowza Video If you're using the `MediaOVP` media type to load your video, you can configure advertisements in our Wowza Video platform. The next two sections describe how to set up ads for your video and live stream content when using the Apple SDK. ### Set up ads for videos To configure your player with the Apple SDK and define how it loads ads for video content from Wowza Video, use the following steps. embed After the previous steps, you can use the `mediaId` and `playerId` values to load the Wowza Video media. These example values are placeholders and must be replaced with your own: ```swift let platformMedia = MediaOVP(mediaId: "5bf95d0e-edb8-4fb8-8b4c-65afa6e2a8ee", playerId: "854eb3d3-ff01-43e6-80ad-97192ea68641") let player.load(ovp: platformMedia) ``` ### Set up ads for live streams To configure your player with the Apple SDK and define how it loads ads for live stream content from Wowza Video, use these steps. For live streams, you can only include pre-roll advertisements. embed After the previous steps, you can use the `mediaId` and `playerId` values to load the Wowza Video media. These example values are placeholders and must be replaced with your own: ```swift let platformMedia = MediaOVP(mediaId: "zxxtsj2b", playerId: "513852a4-18c8-474a-88c7-dc54d4f03555") let player.load(ovp: platformMedia) ``` ## Configure ads programmatically The next few sections cover the configuration required to programmatically work with Google's IMA SDK. You must provide a valid ad schedule so the IMA SDK can prepare and load your advertisements. The `AdSchedule` protocol represents an ad schedule, serving as the basis for the two types of ad schedules available, `AdSheduleWaterfall` and `AdScheduleRemote`. ### Set up AdScheduleWaterfall The `AdScheduleWaterfall` structure represents an ad schedule waterfall for media content. It implements the `AdSchedule` protocol to provide a waterfall-like sequence of ad breaks, helping to specify pre-roll, mid-roll, and post-roll ad breaks for media content. Use this model when utilizing multiple VAST protocols and setting them up programmatically. The VMAP protocol can't be used with this struct. You can use the following properties with the `AdScheduleWaterfall` struct. #### Properties | Property | Description | | --- | --- | | `midAdBreak` | An array of ad breaks to be played during the media content. Use this model when utilizing the VMAP or VAST protocols. If `nil`, no mid-roll ad breaks are played. If the array is empty, mid-roll ad breaks are defined but currently unavailable. | | `postAdBreak` | Ad break to be played after the media content. If `nil`, no post-roll ad break plays. | | `preAdBreak` | Ad break to be played before the media content. If `nil`, no pre-roll ad break plays. | You can declare these properties using the `AdBreak` struct, which defines an ad break array consisting of ad tags and an optional offset. The instance properties for the `AdBreak` struct are listed in the following table. | Property | Description | | --- | --- | | `adTags` | The array of ad tags for the ad break. | | `offset` | The time offset (in seconds) at which the ad break should be inserted during media playback. | #### Example with MediaExternal You can create an `AdScheduleWaterfall` instance with pre-roll, mid-roll, and post-roll, where each `AdBreak` consists of one or more ad tag URLs (such as VAST) and an offset that indicates the time when the break should start. This example creates an ad schedule that consists of: * A pre-roll break with a single ad (offset is ignored). * A mid-roll break with three ads, starting 15 seconds into the playback. * A post-roll break with a single ad (offset is ignored). Info If you wish to use the SDK with a [MediaExternal](/docs/wowza-flowplayer/apple-sdk/set-up-the-player/#load-your-media-files) instance, you must add your ads manually. As in the following example, create an `adSchedule` object and pass it as an argument when you initialize the `MediaExternal` structure. ```swift let preRollBreak = AdBreak(adTags: ["https://link.to.a.vast.file"]) let midRollBreak = AdBreak( adTags: ["https://link.to.a.vast.file", "https://link.to.a.vast.file"], offset: 15 ) let postRollBreak = AdBreak(adTags: ["https://link.to.a.vast.file"]) let adSchedule = AdScheduleWaterfall( preAdBreak: preRollBreak, midAdBreak: midRollBreak, postAdBreak: postRollBreak ) // Add ads manually when using external media let externalMedia = MediaExternal( mediaUrl: URL(string: "https://link.to.a.media.file")!, adSchedule: adSchedule ) ``` ### Set up AdScheduleRemote `AdScheduleRemote` is another structure that implements the `AdSchedule` protocol. It provides the remote VMAP URL pointing to an ad schedule resource. The remote ad schedule can be fetched and parsed to determine ad breaks for the media content. You can use the following properties with this struct. #### Properties | Property | Description | | --- | --- | | `url` | URL pointing to the remote ad schedule resource. | #### Example with MediaExternal You can create an `AdScheduleRemote` instance with a URL to an ad playlist such as VMAP. Make sure that the provided link points to a valid playlist file. Info If you wish to use the SDK with a [MediaExternal](/docs/wowza-flowplayer/apple-sdk/set-up-the-player/#load-your-media-files) instance, you must add your ads manually. As in the following example, create an `adScheduleURL` object and pass it as an argument when you initialize the `MediaExternal` structure. ```swift let mediaURL = URL(string: "https://link.to.a.media.file")! let adScheduleURL = AdScheduleRemote(url: "https://link.to.a.vmap.file") // Add ads manually when using external media let externalMedia = MediaExternal(url: mediaURL, adSchedule: adScheduleURL) ```