Skip to main content

Media Placement

Media placements display in-content ads. The container can render several creative types, including video.


Sample App

The official Teads SDK sample application includes working examples of this format. Use it for implementation examples and as a reference while you set up this placement.

Teads iOS Sample App on GitHub

Example​

UIKit Implementation​

import UIKit
import TeadsSDK

class ArticleViewController: UIViewController {

private var mediaPlacement: TeadsAdPlacementMedia?
private var adView: UIView?

override func viewDidLoad() {
super.viewDidLoad()
setupMediaPlacement()
}

private func setupMediaPlacement() {
// Create configuration
let config = TeadsAdPlacementMediaConfig(
pid: 84242, // Your placement ID
articleUrl: URL(string: "https://example.com/article/123")
)

// Create placement with delegate
mediaPlacement = TeadsAdPlacementMedia(config, delegate: self)

// OR

mediaPlacement = Teads.createPlacement(
with: config,
delegate: self
)

// Load the ad
do {
adView = try mediaPlacement?.loadAd()

// Add to your view hierarchy
if let adView = adView {
insertAdViewInContent(adView)
}
} catch {
print("Failed to load ad: \(error)")
}
}

private func insertAdViewInContent(_ adView: UIView) {
// Add the ad view to your content
// For example, in a scroll view between paragraphs
contentStackView.insertArrangedSubview(adView, at: 2)

// The SDK handles sizing automatically
adView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
adView.leadingAnchor.constraint(equalTo: contentStackView.leadingAnchor),
adView.trailingAnchor.constraint(equalTo: contentStackView.trailingAnchor)
])
}
}

// MARK: - TeadsAdPlacementEventsDelegate
extension ArticleViewController: TeadsAdPlacementEventsDelegate {

func adPlacement(_ placement: TeadsAdPlacementIdentifiable?,
didEmitEvent event: TeadsAdPlacementEventName,
data: [String : Any]?) {

switch event {
case .ready:
print("Ad is ready to be displayed")

case .rendered:
print("Ad has been rendered")

case .viewed:
print("Ad has met viewability criteria")

case .clicked:
print("User clicked on the ad")
// SDK handles URL opening automatically


case .failed:
if let error = data?["error"] as? String {
print("Ad failed to load: \(error)")
}

case .heightUpdated:
if let height = data?["height"] as? CGFloat {
print("Ad height updated to: \(height)")
// No need to do anything, the placement view will handle it's own size.
}

default:
break
}
}
}

SwiftUI Media Implementation (Simplified Approach)​

The SDK provides a native SwiftUI view for Media placements:

import SwiftUI
import TeadsSDK

struct ArticleView: View {
let mediaConfig = TeadsAdPlacementMediaConfig(
pid: 84242,
articleUrl: URL(string: "https://example.com/article/123")
)

var body: some View {
ScrollView {
VStack(spacing: 16) {
Text("Article Title")
.font(.largeTitle)

Text("First paragraph of content...")

// Media Ad Placement - Simple one-liner
TeadsAdPlacementSwiftUIView<TeadsAdPlacementMedia>(
config: mediaConfig,
delegate: nil
)
.frame(maxWidth: .infinity) // Important: Set width explicitly

Text("More article content...")
}
.padding()
}
}
}

Swift-only: TeadsAdPlacementSwiftUIView is a generic SwiftUI struct, and SwiftUI views are not bridgeable to Objective-C.

SwiftUI Media Implementation (With Event Handling)​

If you need to handle events or track ad lifecycle:

import SwiftUI
import TeadsSDK

struct ArticleView: View {
@StateObject private var adManager = MediaAdManager()

var body: some View {
ScrollView {
VStack(spacing: 16) {
Text("Article Title")
.font(.largeTitle)

Text("First paragraph of content...")

// Media Ad Placement with event handling
TeadsAdPlacementSwiftUIView<TeadsAdPlacementMedia>(
config: adManager.mediaConfig,
delegate: adManager
)
.frame(maxWidth: .infinity) // Important: Set width explicitly

Text("More article content...")
}
.padding()
}
}
}

// Simple event handler
class MediaAdManager: NSObject, ObservableObject, TeadsAdPlacementEventsDelegate {
@Published var isLoaded = false
@Published var hasError = false

let mediaConfig = TeadsAdPlacementMediaConfig(
pid: 84242,
articleUrl: URL(string: "https://example.com/article/123")
)

func adPlacement(_ placement: TeadsAdPlacementIdentifiable?,
didEmitEvent event: TeadsAdPlacementEventName,
data: [String : Any]?) {

DispatchQueue.main.async {
switch event {
case .ready, .rendered:
self.isLoaded = true
print("Ad loaded successfully")
case .failed:
self.hasError = true
if let error = data?["error"] as? String {
print("Ad failed: \(error)")
}
case .clicked:
print("Ad clicked")
default:
break
}
}
}
}

Swift-only: TeadsAdPlacementSwiftUIView is a generic SwiftUI struct, and SwiftUI views are not bridgeable to Objective-C.

Best Practices​

Do not open the click URL

The SDK opens the click URL. Do not navigate in this handler or the browser will open twice. Use the event for tracking only.

Dynamic height

Media creatives change height after they load. Do not pin a fixed height. In SwiftUI, do not set .frame(height:).

In a stack or table, pin leading and trailing only. The placement view sizes itself.

In a collection view, cells keep a fixed size until you handle .heightUpdated: use its reported height to update and reload the affected cell.

Ad Lifecycle Listener​

Implement TeadsAdPlacementEventsDelegate to observe playback, clicks, and viewability. See Placement Events Listener for the full event reference and error handling guide.

Checklist​