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)
New Unified Approach (Recommended)
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:
- Swift
- Objective-C
let placement = TeadsAdPlacementMedia(config, delegate: self)
let adView = try placement.loadAd()
// TeadsAdPlacementMediaConfig is a Swift struct and doesn't bridge to Objective-C;
// use the convenience initializer instead (equivalent pid + articleUrl).
NSURL *articleUrl = [NSURL URLWithString:@"https://example.com/article/123"];
TeadsAdPlacementMedia *placement = [[TeadsAdPlacementMedia alloc]
initWithPid:84242
articleUrl:articleUrl
delegate:self];
NSError *error = nil;
UIView *adView = [placement loadAdAndReturnError:&error];
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 v5 | Teads SDK v6 |
|---|---|
Teads.createInReadPlacement | TeadsAdPlacementMedia |
- Media — integration
- Placement Events — events
- Settings — placement and request options
New Features
These are new in v6. Follow the format pages rather than a second copy of the samples:
Advanced Configuration Options
- Settings — placement and request settings
- Privacy
- App Tracking Transparency
Compatibility Matrix
| Feature | Teads SDK v5 | Teads SDK v6 | Notes |
|---|---|---|---|
| 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:
- Check the Integration Guide for detailed examples
- 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!