Skip to main content

Migration Guide for Existing Teads SDK Users

Welcome to the Teads Unified SDK! If you're currently using Teads SDK v5.x, this guide will help you understand what's new and how to take advantage of the enhanced features while maintaining full backward compatibility.

Key Points​

✅ No Breaking Changes - Your existing code continues to work without modifications
✅ New Features Available - Access to Feed placements and unified interfaces
✅ Enhanced Event System - More granular event tracking and monitoring
✅ Complete Backward Compatibility - All existing APIs remain fully functional, but are planned to be deprecated later

What's New​

1. Unified Placement Creation​

While your existing code still works, you now have access to a more convenient unified interface:

Previous Approach (Still Works)​

// Traditional Teads SDK approach - still fully supported
let placement = Teads.createInReadPlacement(
pid: 84242,
settings: settings,
delegate: self
)

placement?.requestAd(requestSettings: requestSettings)

Step 1: Create Media placement config

Swift-only: TeadsAdPlacementMediaConfig is a Swift struct and doesn't bridge to Objective-C — see the Objective-C tab on Step 2, which uses the equivalent convenience initializer directly instead.

// New unified interface - cleaner and more intuitive
let config = TeadsAdPlacementMediaConfig(
pid: 84242,
articleUrl: URL(string: "https://example.com/article/123")
)

Step 2: Create placement:

let placement = TeadsAdPlacementMedia(config, delegate: self)
let adView = try placement.loadAd()

There is also a new generic function on the Teads object that allows you to create any type of placement calling the same function. Please note the config type should match the type of placement.

Swift-only: Teads.createPlacement<T>(with:delegate:) is a Swift generic and generics don't bridge to Objective-C — use each placement class's own convenience initializer instead (see the Objective-C examples throughout this guide).

let mediaPlacement: TeadsAdPlacementMedia? = Teads.createPlacement(with: config, delegate: self)
let feedPlacement: TeadsAdPlacementFeed? = Teads.createPlacement(with: config, delegate: self)

2. Access to Feed Placements​

v6 adds Outbrain-style content widgets next to Media format. Same widget IDs and installation keys as before.

3. Enhanced Event System​

The new unified event system provides consistent event handling across all placement types:

// Unified event delegate
extension YourViewController: TeadsAdPlacementEventsDelegate {
func adPlacement(_ placement: TeadsAdPlacementIdentifiable?,
didEmitEvent event: TeadsAdPlacementEventName,
data: [String : Any]?) {

switch event {
case .ready: // Ad loaded
case .rendered: // Ad displayed
case .viewed: // Viewability met
case .clicked: // User interaction
case .failed: // Error occurred
// ... more events
}
}
}

Full event list and click-URL rules: Placement Events.

Migration Scenarios​

Scenario 1: Keep Existing Implementation​

If your current implementation is working well, no action is required. The SDK maintains full backward compatibility.

// Your existing code continues to work perfectly
class ExistingViewController: UIViewController, TeadsInReadAdPlacementDelegate {

var placement: TeadsInReadAdPlacement?

override func viewDidLoad() {
super.viewDidLoad()

// This still works exactly as before
placement = Teads.createInReadPlacement(
pid: 84242,
delegate: self
)

let settings = TeadsAdRequestSettings { builder in
builder.pageUrl("https://example.com/article/123")
}

placement?.requestAd(requestSettings: settings)
}

// Your existing delegate methods continue to work
func didReceiveAd(ad: TeadsInReadAd, adRatio: TeadsAdRatio) {
// Handle ad display
}

func didUpdateRatio(ad: TeadsInReadAd, adRatio: TeadsAdRatio) {
// Handle ratio update
}

func didFailToReceiveAd(reason: AdFailReason) {
// Handle failure
}

func adOpportunityTrackerView(trackerView: TeadsAdOpportunityTrackerView) {
// Add tracker view for inventory monitoring
}
}

Scenario 2: Gradual Migration to New APIs​

You can migrate to the new APIs gradually, one placement at a time:

class MixedImplementationViewController: UIViewController {

// Mix old and new approaches as needed
var legacyPlacement: TeadsInReadAdPlacement? // Old API
var modernPlacement: TeadsAdPlacementMedia? // New API
var feedPlacement: TeadsAdPlacementFeed? // New feature

override func viewDidLoad() {
super.viewDidLoad()

// Use legacy API for existing placements
setupLegacyPlacement()

// Use new API for new features
setupModernPlacements()
}

private func setupLegacyPlacement() {
// Your existing code
legacyPlacement = Teads.createInReadPlacement(pid: 84242, delegate: self)
// ...
}

private func setupModernPlacements() {
// New unified API
let mediaConfig = TeadsAdPlacementMediaConfig(pid: 84243)
modernPlacement = TeadsAdPlacementMedia(mediaConfig, delegate: self)

// New Feed placement
let feedConfig = TeadsAdPlacementFeedConfig(
articleUrl: URL(string: "https://example.com/article/123")!,
widgetId: "MB_1",
installationKey: "NANOWDGT01",
widgetIndex: 0
)
feedPlacement = TeadsAdPlacementFeed(feedConfig, delegate: self)
}
}

Scenario 3: Full Migration to Unified APIs​

For new implementations or when refactoring, we recommend using the unified APIs:

Before (Traditional Approach)​

class TraditionalViewController: UIViewController, TeadsInReadAdPlacementDelegate, TeadsAdDelegate {

var placement: TeadsInReadAdPlacement?
var adView: TeadsInReadAdView?

override func viewDidLoad() {
super.viewDidLoad()

// Create placement with advanced settings
let placementSettings = TeadsAdPlacementSettings { settings in
settings.disableCrashMonitoring()
settings.disableTeadsAudioSessionManagement()
settings.disableLocation()
settings.enableLightEndScreen()
settings.disableMediaPreload()
settings.userConsent(subjectToGDPR: "1", consent: "consent_string", tcfVersion: .v2, cmpSdkID: 123)
settings.setUsPrivacy(consent: "1---")
settings.setGppConsent(consent: "gpp_string", sectionIds: "2,6,7")
settings.disableBatteryMonitoring()
settings.addExtras("key", "value")
settings.enableDebug()
}

placement = Teads.createInReadPlacement(
pid: 84242,
settings: placementSettings,
delegate: self
)

// Configure request settings
let requestSettings = TeadsAdRequestSettings { builder in
builder.pageUrl("https://example.com/article/123")
builder.enableValidationMode() // For testing only
builder.setMediaScale(.scaleAspectFill)
builder.addExtras("key", "value")
}

// Request ad
placement?.requestAd(requestSettings: requestSettings)
}

// Complete delegate implementation
func didReceiveAd(ad: TeadsInReadAd, adRatio: TeadsAdRatio) {
adView = TeadsInReadAdView(bind: ad)

// Set delegates for additional callbacks
ad.delegate = self
ad.playbackDelegate = self

// Add to view hierarchy
contentView.addSubview(adView!)

// Setup constraints with proper height calculation
let height = adRatio.calculateHeight(for: contentView.bounds.width)
// Setup constraints...
}

func didFailToReceiveAd(reason: AdFailReason) {
// AdFailReason is a plain class, not a switchable enum — switch on its `code`
switch reason.code {
case .errorNoSlot:
print("No ad available")
case .errorNetwork:
print("Network error occurred")
case .errorBadResponse:
print("Invalid ad response")
default:
print("Ad error: \(reason.description)")
}

// Clean up UI
adView?.removeFromSuperview()
adView = nil
}

func didUpdateRatio(ad: TeadsInReadAd, adRatio: TeadsAdRatio) {
// Update layout with new height
let newHeight = adRatio.calculateHeight(for: contentView.bounds.width)
// Update constraints...
}

func adOpportunityTrackerView(trackerView: TeadsAdOpportunityTrackerView) {
// Add tracker view for inventory monitoring
contentView.addSubview(trackerView)
// Setup constraints to fill parent...
}

func didLogMessage(message: String) {
// Handle log messages
print("Teads SDK: \(message)")
}

func willPresentModalView(ad: TeadsAd) -> UIViewController? {
// Return view controller for modal presentation
return self
}

func didCatchError(ad: TeadsAd, error: Error) {
// Handle ad errors
print("Ad error: \(error)")
}

func didClose(ad: TeadsAd) {
// Handle ad close
adView?.removeFromSuperview()
adView = nil
}

func didRecordImpression(ad: TeadsAd) {
// Track impression
print("Ad impression recorded")
}

func didRecordClick(ad: TeadsAd) {
// Track click
print("Ad click recorded")
}

func didExpandedToFullscreen(ad: TeadsAd) {
// Handle fullscreen expansion
print("Ad expanded to fullscreen")
}

func didCollapsedFromFullscreen(ad: TeadsAd) {
// Handle fullscreen collapse
print("Ad collapsed from fullscreen")
}
}

// MARK: - TeadsPlaybackDelegate
extension TraditionalViewController: TeadsPlaybackDelegate {

func adStartPlayingAudio(_ ad: TeadsAd) {
// Handle audio start
print("Ad audio started")
}

func adStopPlayingAudio(_ ad: TeadsAd) {
// Handle audio stop
print("Ad audio stopped")
}

func didPlay(_ ad: TeadsAd) {
// Handle play
print("Ad started playing")
}

func didPause(_ ad: TeadsAd) {
// Handle pause
print("Ad paused")
}

func didComplete(_ ad: TeadsAd) {
// Handle completion
print("Ad completed")
}
}

After (Unified Approach)​

Teads SDK v5Teads SDK v6
Teads.createInReadPlacementTeadsAdPlacementMedia

New Features​

These are new in v6. Follow the format pages rather than a second copy of the samples:

Advanced Configuration Options​

Compatibility Matrix​

FeatureTeads SDK v5Teads SDK v6Notes
Media Placement✅✅Fully backward compatible
Native Placement✅✅Fully backward compatible
Request Settings✅✅All settings preserved
Delegate Methods✅✅Original delegates work
Feed Placement❌✅New feature available
Unified Events❌✅New optional interface
Recommendations API❌✅New feature available
Media Native❌✅New API for TeadsNativeAdView
Advanced Settings✅✅All settings available
Privacy Management✅✅Enhanced privacy features

Support​

If you encounter any issues during migration:

  1. Check the Integration Guide for detailed examples
  2. Contact Support for assistance

Remember: Migration is optional. Your existing code continues to work, and you can adopt new features at your own pace.


Happy coding with the enhanced Teads Unified SDK!