Placement Events Listener
Handle placement events through TeadsAdPlacementEventsDelegate: playback, audio, clicks, and viewability.
Event Reference
| Event | Meaning |
|---|---|
loaded | Ad data was returned by the server |
ready | Ad is ready to be displayed |
rendered | Ad has been rendered on screen |
play | Video creative started playing |
pause | Video creative paused |
complete | Video creative finished playing |
startPlayAudio | Video creative unmuted / started playing audio |
stopPlayAudio | Video creative muted / stopped playing audio |
heightUpdated | Engine reports a new height — read it from data["height"] |
viewed | Ad met viewability criteria |
clicked | User tapped the ad (the SDK opens the landing URL automatically) |
clickedOrganic | User tapped organic (non-paid) content; landing URL is in data["url"] |
failed | No ad to display — fall back to other content |
willPresent | Fired right before the fullscreen interstitial is presented |
presented | Fired when the fullscreen interstitial has been presented |
willDismiss | Fired right before the fullscreen interstitial is dismissed |
dismissed | User closed the fullscreen ad — resume your flow |
Not every placement emits every event — the set your delegate receives depends on the format you integrated.
Conform to TeadsFullScreenEventsDelegate to receive willPresent, presented, willDismiss, and dismissed. Conforming only to TeadsAdPlacementEventsDelegate will not deliver them.
Implementing TeadsAdPlacementEventsDelegate
Basic Implementation
- Swift
- Objective-C
import UIKit
import TeadsSDK
class YourViewController: UIViewController, TeadsAdPlacementEventsDelegate {
var mediaPlacement: TeadsAdPlacementMedia?
var adView: UIView?
override func viewDidLoad() {
super.viewDidLoad()
setupMediaPlacement()
}
private func setupMediaPlacement() {
mediaPlacement = TeadsAdPlacementMedia(
pid: 84242,
articleUrl: URL(string: "https://example.com/article"),
delegate: self
)
do {
adView = try mediaPlacement?.loadAd()
// Add adView to your view hierarchy
} catch {
print("Failed to load ad: \(error)")
}
}
// MARK: - TeadsAdPlacementEventsDelegate
func adPlacement(_ placement: TeadsAdPlacementIdentifiable?,
didEmitEvent event: TeadsAdPlacementEventName,
data: [String : Any]?) {
switch event {
case .ready:
handleAdReady()
case .rendered:
handleAdRendered()
case .play:
handleVideoPlay()
case .pause:
handleVideoPause()
case .complete:
handleVideoComplete()
case .startPlayAudio:
handleAudioStart()
case .stopPlayAudio:
handleAudioStop()
case .clicked:
handleAdClick()
case .viewed:
handleAdViewed()
case .failed:
handleAdFailed(data)
case .heightUpdated:
handleAdHeightUpdate(data)
default:
print("Other event: \(event)")
}
}
}
#import <UIKit/UIKit.h>
#import <TeadsSDK/TeadsSDK-Swift.h>
@interface YourViewController : UIViewController <TeadsAdPlacementEventsDelegate>
@property (nonatomic, strong) TeadsAdPlacementMedia *mediaPlacement;
@property (nonatomic, strong) UIView *adView;
@end
@implementation YourViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupMediaPlacement];
}
- (void)setupMediaPlacement {
self.mediaPlacement = [[TeadsAdPlacementMedia alloc]
initWithPid:84242
articleUrl:[NSURL URLWithString:@"https://example.com/article"]
delegate:self];
NSError *error = nil;
self.adView = [self.mediaPlacement loadAdAndReturnError:&error];
if (error) {
NSLog(@"Failed to load ad: %@", error);
return;
}
// Add self.adView to your view hierarchy
}
#pragma mark - TeadsAdPlacementEventsDelegate
- (void)adPlacement:(id<TeadsAdPlacementIdentifiable>)placement
didEmitEvent:(TeadsAdPlacementEventName)event
data:(NSDictionary<NSString *, id> *)data {
switch (event) {
case TeadsAdPlacementEventNameReady:
[self handleAdReady];
break;
case TeadsAdPlacementEventNameRendered:
[self handleAdRendered];
break;
case TeadsAdPlacementEventNamePlay:
[self handleVideoPlay];
break;
case TeadsAdPlacementEventNamePause:
[self handleVideoPause];
break;
case TeadsAdPlacementEventNameComplete:
[self handleVideoComplete];
break;
case TeadsAdPlacementEventNameStartPlayAudio:
[self handleAudioStart];
break;
case TeadsAdPlacementEventNameStopPlayAudio:
[self handleAudioStop];
break;
case TeadsAdPlacementEventNameClicked:
[self handleAdClick];
break;
case TeadsAdPlacementEventNameViewed:
[self handleAdViewed];
break;
case TeadsAdPlacementEventNameFailed:
[self handleAdFailed:data];
break;
case TeadsAdPlacementEventNameHeightUpdated:
[self handleAdHeightUpdate:data];
break;
default:
NSLog(@"Other event: %ld", (long)event);
break;
}
}
@end
Fullscreen Events (Interstitial)
Interstitial delivers willPresent, presented, willDismiss, and dismissed through TeadsFullScreenEventsDelegate, a separate protocol that extends TeadsAdPlacementEventsDelegate. Conform to it and implement fullScreenPlacement(_:didEmitEvent:data:) alongside the regular adPlacement(_:didEmitEvent:data:) — both methods are called on the same object, passed once as the delegate: argument when you create the placement. Because the protocol extends TeadsAdPlacementEventsDelegate, adPlacement(_:didEmitEvent:data:) still receives the full ad event set (ready, failed, clicked, viewed, and so on) shown in Basic Implementation above — it isn't a reduced or fullscreen-only variant.
- Swift
- Objective-C
import TeadsSDK
class InterstitialManager: NSObject {
private var placement: TeadsAdPlacementInterstitial?
func load() {
let config = TeadsAdPlacementInterstitialConfig(
articleUrl: URL(string: "https://example.com/article")!,
widgetId: "INT_APP_1",
installationKey: "NANOWDGT01"
)
placement = Teads.createPlacement(with: config, delegate: self)
placement?.loadAd()
}
}
extension InterstitialManager: TeadsFullScreenEventsDelegate {
// Ad events (load result, viewability, clicks)
func adPlacement(_ placement: TeadsAdPlacementIdentifiable?,
didEmitEvent event: TeadsAdPlacementEventName,
data: [String: Any]?) {
if event == .ready {
self.placement?.show()
}
}
// Fullscreen lifecycle events
func fullScreenPlacement(
_ placement: TeadsAdPlacementIdentifiable?,
didEmitEvent event: TeadsFullScreenEventName,
data: [String: Any]?
) {
switch event {
case .willPresent:
print("Interstitial about to present")
case .presented:
print("Interstitial presented")
case .willDismiss:
print("Interstitial about to dismiss")
case .dismissed:
print("Interstitial dismissed")
@unknown default:
break
}
}
}
#import <TeadsSDK/TeadsSDK-Swift.h>
@interface InterstitialManager : NSObject <TeadsFullScreenEventsDelegate>
@property (nonatomic, strong) TeadsAdPlacementInterstitial *placement;
@end
@implementation InterstitialManager
- (void)load {
// Teads.createPlacement(with:delegate:) is a Swift-only generic — create the
// placement directly with its Objective-C-friendly convenience initializer
self.placement = [[TeadsAdPlacementInterstitial alloc]
initWithArticleUrl:[NSURL URLWithString:@"https://example.com/article"]
widgetId:@"INT_APP_1"
installationKey:@"NANOWDGT01"
delegate:self];
[self.placement loadAd];
}
#pragma mark - TeadsAdPlacementEventsDelegate
- (void)adPlacement:(id<TeadsAdPlacementIdentifiable>)placement
didEmitEvent:(TeadsAdPlacementEventName)event
data:(NSDictionary<NSString *, id> *)data {
if (event == TeadsAdPlacementEventNameReady) {
[self.placement showFrom:nil];
}
}
#pragma mark - TeadsFullScreenEventsDelegate
- (void)fullScreenPlacement:(id<TeadsAdPlacementIdentifiable>)placement
didEmitEvent:(TeadsFullScreenEventName)event
data:(NSDictionary<NSString *, id> *)data {
switch (event) {
case TeadsFullScreenEventNameWillPresent:
NSLog(@"Interstitial about to present");
break;
case TeadsFullScreenEventNamePresented:
NSLog(@"Interstitial presented");
break;
case TeadsFullScreenEventNameWillDismiss:
NSLog(@"Interstitial about to dismiss");
break;
case TeadsFullScreenEventNameDismissed:
NSLog(@"Interstitial dismissed");
break;
default:
break;
}
}
@end
The delegate must conform to TeadsFullScreenEventsDelegate (which extends TeadsAdPlacementEventsDelegate) to receive both ad and fullscreen lifecycle events. Passing a delegate that does not conform to TeadsFullScreenEventsDelegate results in a warning, and the delegate keeps receiving regular ad events but misses the four fullscreen lifecycle events (willPresent, presented, willDismiss, dismissed).
User Interaction Events
Click Event
case .clicked:
print("Ad clicked")
The SDK opens the click URL. Do not navigate in this handler or the browser will open twice. Use the event for tracking only.
There is also a .clickedOrganic case, emitted when a user clicks on organic (non-paid) content in placements that support it, such as Feed or Recommendations.
Viewed Event
case .viewed:
print("Ad viewability threshold reached")
Error Handling
Failed Event
case .failed:
print("Ad failed to load, data: \(data)")