Interstitial Placement
Interstitial Placement
Interstitial placements display a fullscreen ad that the user can dismiss. Unlike other placement types, an interstitial is loaded in the background and shown at a natural transition point in your app.
The direct interstitial integration requires no mediation SDK. If you are using Google Ad Manager or AdMob, see the GMA mediation guide instead.
Configuration
- Swift
- Objective-C
import TeadsSDK
let config = TeadsAdPlacementInterstitialConfig(
articleUrl: URL(string: "https://example.com/article")!,
widgetId: "INT_MW_1", // Your widget ID
installationKey: "NANOWDGT01", // Your installation key
floorPrice: 2 // Optional: minimum bid price in US dollars
)
#import <TeadsSDK/TeadsSDK-Swift.h>
// Objective-C has no separate Config type — pass parameters (including the
// optional floorPrice) directly to the placement's convenience initializer.
TeadsAdPlacementInterstitial *placement = [[TeadsAdPlacementInterstitial alloc] initWithArticleUrl:[NSURL URLWithString:@"https://example.com/article"]
widgetId:@"INT_MW_1" // Your widget ID
installationKey:@"NANOWDGT01" // Your installation key
floorPrice:2 // Optional: minimum bid price in US dollars
delegate:nil];
Loading an Interstitial
Create the placement and load it ahead of the moment you want to show it:
- 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_MW_1",
installationKey: "NANOWDGT01"
)
placement = Teads.createPlacement(with: config, delegate: self)
placement?.loadAd()
}
}
#import <TeadsSDK/TeadsSDK-Swift.h>
@interface InterstitialManager : NSObject
@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_MW_1"
installationKey:@"NANOWDGT01"
delegate:self];
[self.placement loadAd];
}
@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 will result in a warning and no events being delivered.
Presenting the Ad
Check isReady before calling show(from:):
- Swift
- Objective-C
func showAd(from viewController: UIViewController) {
guard let placement, placement.isReady else {
print("Ad not ready")
return
}
placement.show(from: viewController)
}
- (void)showAdFrom:(UIViewController *)viewController {
if (!self.placement || !self.placement.isReady) {
NSLog(@"Ad not ready");
return;
}
[self.placement showFrom:viewController];
}
show(from:) accepts an optional UIViewController. If nil is passed, the SDK falls back to the application's top view controller automatically.
Handling Events
Implement TeadsFullScreenEventsDelegate to respond to ad and lifecycle events:
- Swift
- Objective-C
extension InterstitialManager: TeadsFullScreenEventsDelegate {
// Ad events (load result, viewability, clicks)
func adPlacement(
_ placement: TeadsAdPlacementIdentifiable?,
didEmitEvent event: TeadsAdPlacementEventName,
data: [String: Any]?
) {
switch event {
case .ready:
print("Ad loaded — ready to show")
case .failed:
let reason = data?["reason"] as? String ?? "Unknown"
print("Ad failed: \(reason)")
// reason is "Ad expired" when the cache TTL elapses before show()
case .rendered:
print("Ad appeared on screen")
case .viewed:
print("Viewability threshold reached")
case .clicked:
print("Ad clicked")
// The SDK opens the URL automatically — do not navigate manually
default:
break
}
}
// Fullscreen lifecycle events
func fullScreenPlacement(
_ placement: TeadsAdPlacementIdentifiable?,
didEmitEvent event: TeadsFullScreenEventName,
data: [String: Any]?
) {
switch event {
case .willPresent:
print("Ad about to present — pause audio, suspend timers")
case .presented:
print("Ad is now fullscreen")
case .willDismiss:
print("Ad about to dismiss")
case .dismissed:
print("Ad dismissed — resume app state")
placement?.invalidate()
@unknown default:
break
}
}
}
@interface InterstitialManager () <TeadsFullScreenEventsDelegate>
@end
@implementation InterstitialManager (TeadsFullScreenEventsDelegate)
// Ad events (load result, viewability, clicks)
- (void)adPlacement:(id<TeadsAdPlacementIdentifiable>)placement
didEmitEvent:(TeadsAdPlacementEventName)event
data:(NSDictionary<NSString *, id> *)data {
switch (event) {
case TeadsAdPlacementEventNameReady:
NSLog(@"Ad loaded — ready to show");
break;
case TeadsAdPlacementEventNameFailed: {
NSString *reason = data[@"reason"] ?: @"Unknown";
NSLog(@"Ad failed: %@", reason);
// reason is "Ad expired" when the cache TTL elapses before show()
break;
}
case TeadsAdPlacementEventNameRendered:
NSLog(@"Ad appeared on screen");
break;
case TeadsAdPlacementEventNameViewed:
NSLog(@"Viewability threshold reached");
break;
case TeadsAdPlacementEventNameClicked:
NSLog(@"Ad clicked");
// The SDK opens the URL automatically — do not navigate manually
break;
default:
break;
}
}
// Fullscreen lifecycle events
- (void)fullScreenPlacement:(id<TeadsAdPlacementIdentifiable>)placement
didEmitEvent:(TeadsFullScreenEventName)event
data:(NSDictionary<NSString *, id> *)data {
switch (event) {
case TeadsFullScreenEventNameWillPresent:
NSLog(@"Ad about to present — pause audio, suspend timers");
break;
case TeadsFullScreenEventNamePresented:
NSLog(@"Ad is now fullscreen");
break;
case TeadsFullScreenEventNameWillDismiss:
NSLog(@"Ad about to dismiss");
break;
case TeadsFullScreenEventNameDismissed:
NSLog(@"Ad dismissed — resume app state");
[self.placement invalidate];
break;
default:
break;
}
}
@end
Ad Cache TTL
Once loaded, the ad must be shown within its cache TTL or it expires. The default TTL is 3600 seconds (1 hour), configurable server-side per widget. When the ad expires, .failed is emitted with reason: "Ad expired" and the placement is automatically cleaned up. Call loadAd() again to fetch a fresh ad.
Cleanup
Call invalidate() when you are done with a placement or want to discard a loaded ad before showing it:
- Swift
- Objective-C
// Discard without showing
placement?.invalidate()
// Or set to nil to let ARC clean up
placement = nil
// Discard without showing
[self.placement invalidate];
// Or set to nil to let ARC clean up
self.placement = nil;
invalidate() is safe to call multiple times. After invalidation the same placement instance can be reloaded via loadAd().