Appearance
Opera Ads iOS SDK - Integration Guide
Overview
The Opera Ads iOS SDK enables developers to monetize their iOS applications with high-quality ads. The SDK supports multiple ad formats including Native, Banner (MRAID), Interstitial, Rewarded Video, Rewarded Interstitial, and App Open ads, with minimal setup and robust event callbacks.
Key Features
- Multiple Ad Formats: Native, Banner, Interstitial, Rewarded Video, Rewarded Interstitial, and App Open
- Bidding Support: Waterfall, Client-to-Server (C2S) Bidding, and Server-to-Server (S2S) Bidding
- Dual Language API: Full Swift and Objective-C support
- Mediation Ready: Adapters for AdMob, AppLovin MAX, and TopOn
- Privacy Compliant: GDPR, CCPA, and COPPA support
- Rich Media: MRAID 2.0 support for interactive ads
- Debug Logging: Comprehensive logging system for development
Prerequisites
Before integrating the Opera Ads SDK, ensure you meet the following requirements:
Development Environment
- Xcode: 14.0 or higher
- iOS Deployment Target: iOS 13.0 or higher
- Language: Swift 5.0+ or Objective-C
- CocoaPods: 1.10.0 or higher (if using CocoaPods)
Account Setup
- Active Opera Ads publisher account
- Application ID (format:
pub{}/ep{}/app{}) - iOS App ID (iTunes App ID)
- Placement IDs for each ad unit
Required Permissions
Add the following to your Info.plist:
xml
<!-- Required for ad serving -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>Location Data (Optional)
The SDK never requests location permission. If your app already has location permission granted by the user, the SDK will passively read the cached location with approximately 10 km precision (latitude/longitude rounded to 1 decimal place) to improve ad targeting — no additional Info.plist configuration is needed for this.
If your app does not use location at all, no action is required.
Installation & Setup
Method 1: CocoaPods (Recommended)
Add the following to your Podfile:
ruby
platform :ios, '13.0'
target 'YourApp' do
use_frameworks!
# Opera Ads SDK
pod 'OpAdxSdk', '~> 2.9.1'
endThen run:
bash
pod installMethod 2: Manual Integration
- Download the latest
OpAdxSdk.xcframeworkfrom the releases page - Drag
OpAdxSdk.xcframeworkinto your Xcode project - In General > Frameworks, Libraries, and Embedded Content, select Embed & Sign for the framework
Dependency Configuration
The SDK has zero external third-party pod dependencies. Everything you need is bundled within the SDK itself:
OMSDK_Opera.xcframework— Open Measurement SDK, vendored directly inside the SDK package. No separate pod installation is required.- All networking is implemented using Apple's native
URLSession. - Privacy consent is handled via Apple's native
AppTrackingTransparencyframework (a system framework, no pod required).
When integrating via CocoaPods, simply add:
ruby
pod 'OpAdxSdk', '~> 2.9.1'No additional pod entries are needed.
Initialization
Initialize the SDK in your AppDelegate before loading any ads. The SDK supports both synchronous and asynchronous initialization.
Swift Example
swift
import UIKit
import OpAdxSdk
// Replace with your own values from Opera Ads Publisher Portal
let kApplicationId = "pub13423013211200/ep13423013211584/app14170937163904"
let kIOSAppId = "1444253128" // Your App Store ID (numeric part of the App Store URL)
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Optional: Enable debug logging (development only)
// OpAdxLogger.logLevel = .debug
// Create SDK configuration
let config = OpAdxSdkInitConfig.create(
applicationId: kApplicationId,
iOSAppId: kIOSAppId
)
// Initialize SDK with callbacks
OpAdxSDK.initialize(
withConfig: config,
onSuccess: {
print("Opera Ads SDK initialized successfully")
},
onError: { error in
print("SDK initialization failed: \(error.localizedDescription)")
}
)
return true
}
}Objective-C Example
objective-c
#import "AppDelegate.h"
#import <OpAdxSdk/OpAdxSdk.h>
// Replace with your own values from Opera Ads Publisher Portal
static NSString *const kApplicationId = @"pub13423013211200/ep13423013211584/app14170937163904";
static NSString *const kIOSAppId = @"1444253128"; // Your App Store ID (numeric part of the App Store URL)
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Optional: Enable debug logging (development only)
// OpAdxLogger.logLevel = OpAdxLogLevelDebug;
// Create SDK configuration
OpAdxSdkInitConfig *config = [OpAdxSdkInitConfig
createWithApplicationId:kApplicationId
iOSAppId:kIOSAppId
publisherName:nil];
// Initialize SDK with callbacks
[OpAdxSDK initializeWithConfig:config
onSuccess:^{
NSLog(@"Opera Ads SDK initialized successfully");
}
onError:^(NSError *error) {
NSLog(@"SDK initialization failed: %@", error.localizedDescription);
}];
return YES;
}
@endInitialization Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
applicationId | String | Yes | Your application ID (format: pub{}/ep{}/app{}) |
iOSAppId | String | Yes | App Store ID — the numeric part of your App Store URL (e.g., xxxxxxxxxxx from https://apps.apple.com/app/xxxxxxxxxxx). If your app is not yet published, use any placeholder value (e.g., "") and update it before release. |
publisherName | String | No | Publisher name for reporting |
coppa | Boolean | No | COPPA compliance flag |
usPrivacy | String | No | CCPA/US Privacy string |
Ad Formats
1. Native Ads
Native ads provide customizable ad content that matches your app's look and feel.
Swift Implementation
swift
import OpAdxSdk
let kNativePlacementId = "s14198263063424" // Replace with your placement ID
class NativeAdViewController: UIViewController {
private var nativeAd: OpAdxNativeAd?
private var adContainerView: UIView!
func loadNativeAd() {
nativeAd = OpAdxNativeAd(
placementId: kNativePlacementId,
auctionType: .regular
)
let listener = OpAdxNativeAdListenerImp(
onAdLoaded: { [weak self] ad in
guard let self = self, let nativeAd = ad as? OpAdxNativeAd else { return }
self.renderNativeAd(nativeAd)
},
onAdFailedToLoad: { error in
print("Native ad failed to load: \(error.message)")
},
onAdImpression: {
print("Native ad impression recorded")
},
onAdClicked: {
print("Native ad clicked")
}
)
nativeAd?.loadAd(listener: listener)
}
func renderNativeAd(_ nativeAd: OpAdxNativeAd) {
// Build your custom ad layout
let containerView = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 400))
let titleLabel = UILabel()
titleLabel.text = nativeAd.title()
let bodyLabel = UILabel()
bodyLabel.text = nativeAd.descriptionStr()
let ctaButton = UIButton(type: .system)
ctaButton.setTitle(nativeAd.callToAction(), for: .normal)
let iconImageView = UIImageView()
// Load icon from nativeAd.iconUrl()
let mediaView = nativeAd.createMediaView()
// Add subviews to containerView (layout omitted for brevity)
containerView.addSubview(titleLabel)
containerView.addSubview(bodyLabel)
containerView.addSubview(ctaButton)
containerView.addSubview(iconImageView)
containerView.addSubview(mediaView)
view.addSubview(containerView)
// Register views for interaction tracking and ad choice icon
let rootView = OpAdxNativeAdRootView(root: containerView)
let interactionViews = OpAdxInteractionViews(
mediaView: mediaView,
titleView: titleLabel,
bodyView: bodyLabel,
callToActionView: ctaButton,
iconView: iconImageView,
extraClickableViews: nil
)
nativeAd.registerInteractionViews(
container: rootView,
interactionViews: interactionViews,
adChoicePosition: .topRight
)
}
func destroyNativeAd() {
nativeAd?.destroy()
nativeAd = nil
}
}Objective-C Implementation
objective-c
#import <OpAdxSdk/OpAdxSdk.h>
static NSString *const kNativePlacementId = @"s14198263063424"; // Replace with your placement ID
@interface NativeAdViewController () <OpAdxNativeAdDelegate>
@property (nonatomic, strong) OpAdxNativeAdBridge *nativeAd;
@end
@implementation NativeAdViewController
- (void)loadNativeAd {
self.nativeAd = [[OpAdxNativeAdBridge alloc]
initWithPlacementId:kNativePlacementId
auctionType:AdAuctionTypeRegular];
self.nativeAd.delegate = self;
[self.nativeAd loadAd];
}
#pragma mark - OpAdxNativeAdDelegate
- (void)nativeAdDidLoad:(OpAdxNativeAdBridge *)nativeAd {
[self renderNativeAd:nativeAd];
}
- (void)nativeAd:(OpAdxNativeAdBridge *)nativeAd didFailWithError:(OpAdxAdError *)error {
NSLog(@"Native ad failed: %@", error.message);
}
- (void)nativeAdDidDownloadMedia:(OpAdxNativeAdBridge *)nativeAd {
NSLog(@"Native ad media downloaded");
}
- (void)nativeAdWillLogImpression:(OpAdxNativeAdBridge *)nativeAd {
NSLog(@"Native ad impression");
}
- (void)nativeAdDidClick:(OpAdxNativeAdBridge *)nativeAd {
NSLog(@"Native ad clicked");
}
- (void)nativeAdDidFinishHandlingClick:(OpAdxNativeAdBridge *)nativeAd {
NSLog(@"Native ad finished handling click");
}
@endOpAdxNativeAdDelegate Methods (Objective-C)
All delegate methods are optional:
| Method | Description |
|---|---|
nativeAdDidLoad: | Ad loaded successfully |
nativeAd:didFailWithError: | Ad failed to load |
nativeAdDidDownloadMedia: | Media assets downloaded |
nativeAdWillLogImpression: | Impression is about to be recorded |
nativeAdDidClick: | Ad was clicked |
nativeAdDidFinishHandlingClick: | Click handling completed |
Native Ad Assets
| Swift Method | ObjC Property | Return Type | Description |
|---|---|---|---|
title() | title | String? | Ad headline |
descriptionStr() | adDescription | String? | Ad description text |
callToAction() | callToAction | String? | CTA button text (e.g., "Install") |
iconUrl() | iconUrl | URL? | Square icon image URL |
imageUrl() | imageUrl | URL? | Main creative image URL |
starRating() | starRating | NSNumber? | App rating (0–5) |
sponsor() | sponsor | String? | Advertiser / sponsor name |
privacy() | privacy | URL? | Privacy policy URL |
createMediaView() | createMediaView | OpAdxMediaView | Video/image media view (call on main thread) |
2. Banner Ads
Banner ads are rectangular ads that appear at the top or bottom of your app's interface.
Supported Sizes
| Size Constant | Dimensions | Description |
|---|---|---|
BANNER | 320x50 | Standard banner |
LARGE_BANNER | 320x100 | Large banner |
MEDIUM_RECTANGLE | 300x250 | Medium rectangle |
FULL_BANNER | 468x60 | Full banner |
LEADERBOARD | 728x90 | Leaderboard (iPad) |
SMART_BANNER | Screen width x auto | Smart banner (adapts to device) |
Swift Implementation
swift
import OpAdxSdk
let kBannerPlacementId = "s14170965187264" // Replace with your placement ID
class BannerViewController: UIViewController {
private var bannerAdView: OpAdxBannerAdView?
func loadBannerAd() {
// Create banner ad view
bannerAdView = OpAdxBannerAdView()
bannerAdView?.setPlacementId(kBannerPlacementId)
bannerAdView?.setAdSize(.MEDIUM_RECTANGLE)
// Create listener
let listener = OpAdxBannerAdListenerImp(
onAdLoaded: { [weak self] bannerAdInfo in
guard let self = self, let info = bannerAdInfo as? OpAdxBannerAdInfo else { return }
print("Banner loaded: \(info.adSize)")
self.showBanner()
},
onAdFailedToLoad: { error in
print("Banner failed to load: \(error.message)")
},
onAdImpression: {
print("Banner impression")
},
onAdClicked: {
print("Banner clicked")
}
)
// Load ad
bannerAdView?.loadAd(listener: listener)
}
func showBanner() {
guard let bannerAdView = bannerAdView else { return }
// Add to view hierarchy
view.addSubview(bannerAdView)
bannerAdView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
bannerAdView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
bannerAdView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
bannerAdView.widthAnchor.constraint(equalToConstant: 300),
bannerAdView.heightAnchor.constraint(equalToConstant: 250)
])
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
bannerAdView?.pause()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
bannerAdView?.resume()
}
func destroyBanner() {
bannerAdView?.destroy()
bannerAdView = nil
}
}Objective-C Implementation
objc
#import <OpAdxSdk/OpAdxSdk.h>
static NSString *const kBannerPlacementId = @"s14170965187264"; // Replace with your placement ID
@interface BannerViewController () <OpAdxBannerAdDelegate>
@property (nonatomic, strong) OpAdxBannerAdBridge *bannerAdView;
@end
@implementation BannerViewController
- (void)loadBannerAd {
[self destroyBanner];
// Create banner ad with placement ID and size
self.bannerAdView = [[OpAdxBannerAdBridge alloc] initWithPlacementId:kBannerPlacementId
adSize:OpAdxAdSize.MEDIUM_RECTANGLE];
self.bannerAdView.delegate = self;
// Load ad
[self.bannerAdView loadAd];
}
- (void)showBanner {
if (!self.bannerAdView) return;
[self.view addSubview:self.bannerAdView];
self.bannerAdView.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[self.bannerAdView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
[self.bannerAdView.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
[self.bannerAdView.widthAnchor constraintEqualToConstant:300],
[self.bannerAdView.heightAnchor constraintEqualToConstant:250]
]];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.bannerAdView pause];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.bannerAdView resume];
}
- (void)destroyBanner {
[self.bannerAdView destroy];
self.bannerAdView = nil;
}
#pragma mark - OpAdxBannerAdDelegate
- (void)bannerAdDidLoad:(OpAdxBannerAdBridge *)bannerAd {
NSLog(@"Banner loaded: %@", bannerAd.adSize);
[self showBanner];
}
- (void)bannerAd:(OpAdxBannerAdBridge *)bannerAd didFailWithError:(OpAdxAdError *)error {
NSLog(@"Banner failed to load: %@", error.message);
}
- (void)bannerAdDidDisplay:(OpAdxBannerAdBridge *)bannerAd {
NSLog(@"Banner impression");
}
- (void)bannerAdDidClick:(OpAdxBannerAdBridge *)bannerAd {
NSLog(@"Banner clicked");
}
@endOpAdxBannerAdDelegate Methods (Objective-C)
| Method | Description |
|---|---|
bannerAdDidLoad: | Called when the banner ad is loaded successfully |
bannerAd:didFailWithError: | Called when the banner ad fails to load |
bannerAdDidDisplay: | Called when the banner ad records an impression |
bannerAdDidClick: | Called when the banner ad is clicked |
bannerAdDidClose: | Called when the banner ad is closed |
bannerAdWillLeaveApplication: | Called when the user leaves the app after clicking |
bannerAdDidReturnToApplication: | Called when the user returns to the app |
All delegate methods are optional.
Auto-Refresh Configuration
swift
// Set auto-refresh interval (30-120 seconds)
bannerAdView?.setAutoRefreshInterval(60)
// Or disable auto-refresh
bannerAdView?.setAutoRefreshInterval(0)3. Interstitial Ads
Interstitial ads are full-screen ads that cover the interface of their host app.
Swift Implementation
swift
import OpAdxSdk
let kInterstitialPlacementId = "s14198264979520" // Replace with your placement ID
class InterstitialViewController: UIViewController {
private var interstitialAd: OpAdxInterstitialAd?
func loadInterstitialAd() {
destroyAd()
// Create interstitial ad
interstitialAd = OpAdxInterstitialAd(
placementId: kInterstitialPlacementId,
auctionType: .regular
)
// Create load listener
let loadListener = OpAdxInterstitialAdLoadListenerImp(
onAdLoaded: { [weak self] ad in
print("Interstitial loaded")
},
onAdFailedToLoad: { error in
print("Interstitial failed to load: \(error.message)")
}
)
// Load ad
interstitialAd?.load(placementId: kInterstitialPlacementId, listener: loadListener)
}
func showInterstitialAd() {
guard let interstitialAd = interstitialAd else { return }
// Check if ad is still valid
if interstitialAd.isAdInvalidated() {
print("Ad has expired")
loadInterstitialAd()
return
}
// Create interaction listener
let interactionListener = OpAdxInterstitialAdInteractionListenerImp(
onAdClicked: {
print("Interstitial clicked")
},
onAdDisplayed: {
print("Interstitial displayed")
},
onAdDismissed: { [weak self] in
print("Interstitial dismissed")
self?.interstitialAd = nil
},
onAdFailedToShow: { error in
print("Interstitial failed to show: \(error.message)")
}
)
// Show ad
interstitialAd.show(on: self, listener: interactionListener)
}
func destroyAd() {
interstitialAd?.destroy()
interstitialAd = nil
}
}Objective-C Implementation
objc
#import <OpAdxSdk/OpAdxSdk.h>
static NSString *const kInterstitialPlacementId = @"s14198264979520"; // Replace with your placement ID
@interface InterstitialViewController () <OpAdxInterstitialAdDelegate>
@property (nonatomic, strong) OpAdxInterstitialAdBridge *interstitialAd;
@end
@implementation InterstitialViewController
- (void)loadInterstitialAd {
[self destroyAd];
// Create interstitial ad
self.interstitialAd = [[OpAdxInterstitialAdBridge alloc] initWithPlacementId:kInterstitialPlacementId
auctionType:AdAuctionTypeRegular];
self.interstitialAd.delegate = self;
// Load ad
[self.interstitialAd loadAd];
}
- (void)showInterstitialAd {
if (!self.interstitialAd) return;
// Check if ad is still valid
if (![self.interstitialAd isAdValid]) {
NSLog(@"Ad has expired");
[self loadInterstitialAd];
return;
}
// Show ad
[self.interstitialAd showAdFrom:self];
}
- (void)destroyAd {
self.interstitialAd = nil;
}
#pragma mark - OpAdxInterstitialAdDelegate
- (void)interstitialAdDidLoad:(OpAdxInterstitialAdBridge *)interstitialAd {
NSLog(@"Interstitial loaded");
}
- (void)interstitialAd:(OpAdxInterstitialAdBridge *)interstitialAd didFailWithError:(OpAdxAdError *)error {
NSLog(@"Interstitial failed to load: %@", error.message);
}
- (void)interstitialAdDidDisplay:(OpAdxInterstitialAdBridge *)interstitialAd {
NSLog(@"Interstitial displayed");
}
- (void)interstitialAdDidClick:(OpAdxInterstitialAdBridge *)interstitialAd {
NSLog(@"Interstitial clicked");
}
- (void)interstitialAdDidClose:(OpAdxInterstitialAdBridge *)interstitialAd {
NSLog(@"Interstitial dismissed");
self.interstitialAd = nil;
}
- (void)interstitialAd:(OpAdxInterstitialAdBridge *)interstitialAd didFailToDisplayWithError:(OpAdxAdError *)error {
NSLog(@"Interstitial failed to show: %@", error.message);
}
@endOpAdxInterstitialAdDelegate Methods (Objective-C)
| Method | Description |
|---|---|
interstitialAdDidLoad: | Called when the interstitial ad is loaded successfully |
interstitialAd:didFailWithError: | Called when the interstitial ad fails to load |
interstitialAdDidDisplay: | Called when the interstitial ad is displayed |
interstitialAdDidClick: | Called when the interstitial ad is clicked |
interstitialAdDidClose: | Called when the interstitial ad is closed |
interstitialAd:didFailToDisplayWithError: | Called when the interstitial ad fails to show |
All delegate methods are optional.
4. Rewarded Video Ads
Rewarded video ads reward users for watching short videos.
Swift Implementation
swift
import OpAdxSdk
let kRewardedPlacementId = "s14198592226752" // Replace with your placement ID
class RewardedViewController: UIViewController {
private var rewardedAd: OpAdxRewardedAd?
func loadRewardedAd() {
destroyAd()
// Create rewarded ad
rewardedAd = OpAdxRewardedAd(
placementId: kRewardedPlacementId,
auctionType: .regular
)
// Create load listener
let loadListener = OpAdxRewardedAdLoadListenerImp(
onAdLoaded: { [weak self] ad in
print("Rewarded ad loaded")
},
onAdFailedToLoad: { error in
print("Rewarded ad failed to load: \(error.message)")
}
)
// Load ad
rewardedAd?.load(placementId: kRewardedPlacementId, listener: loadListener)
}
func showRewardedAd() {
guard let rewardedAd = rewardedAd else { return }
if rewardedAd.isAdInvalidated() {
print("Ad has expired")
loadRewardedAd()
return
}
// Set scene ID (optional, for analytics)
rewardedAd.setSceneId("level_complete")
// Set SSV options (optional, for server-side verification)
let ssvOptions = RewardSsvOptions.Builder()
.userId("user_12345")
.customData("level=5&score=1000")
.build()
rewardedAd.setRewardSsvOptions(ssvOptions)
// Create interaction listener
let interactionListener = OpAdxRewardedAdInteractionListenerImp(
onAdClicked: {
print("Rewarded ad clicked")
},
onAdDisplayed: {
print("Rewarded ad displayed")
},
onAdDismissed: { [weak self] in
print("Rewarded ad dismissed")
self?.rewardedAd = nil
},
onAdFailedToShow: { error in
print("Rewarded ad failed to show: \(error.message)")
},
onUserRewarded: { reward in
// reward.type: String, reward.amount: Int
print("User rewarded: \(reward.type) x \(reward.amount)")
}
)
// Show ad
rewardedAd.show(on: self, listener: interactionListener)
}
func destroyAd() {
rewardedAd?.destroy()
rewardedAd = nil
}
}Objective-C Implementation
objc
#import <OpAdxSdk/OpAdxSdk.h>
static NSString *const kRewardedPlacementId = @"s14198592226752"; // Replace with your placement ID
@interface RewardedViewController () <OpAdxRewardedAdDelegate>
@property (nonatomic, strong) OpAdxRewardedAdBridge *rewardedAd;
@end
@implementation RewardedViewController
- (void)loadRewardedAd {
[self destroyAd];
// Create rewarded ad
self.rewardedAd = [[OpAdxRewardedAdBridge alloc] initWithPlacementId:kRewardedPlacementId
auctionType:AdAuctionTypeRegular];
self.rewardedAd.delegate = self;
// Load ad
[self.rewardedAd loadAd];
}
- (void)showRewardedAd {
if (!self.rewardedAd) return;
if (![self.rewardedAd isAdValid]) {
NSLog(@"Ad has expired");
[self loadRewardedAd];
return;
}
// Show ad
[self.rewardedAd showAdFrom:self];
}
- (void)destroyAd {
self.rewardedAd = nil;
}
#pragma mark - OpAdxRewardedAdDelegate
- (void)rewardedAdDidLoad:(OpAdxRewardedAdBridge *)rewardedAd {
NSLog(@"Rewarded ad loaded");
}
- (void)rewardedAd:(OpAdxRewardedAdBridge *)rewardedAd didFailWithError:(OpAdxAdError *)error {
NSLog(@"Rewarded ad failed to load: %@", error.message);
}
- (void)rewardedAdDidDisplay:(OpAdxRewardedAdBridge *)rewardedAd {
NSLog(@"Rewarded ad displayed");
}
- (void)rewardedAdDidClick:(OpAdxRewardedAdBridge *)rewardedAd {
NSLog(@"Rewarded ad clicked");
}
- (void)rewardedAdDidClose:(OpAdxRewardedAdBridge *)rewardedAd {
NSLog(@"Rewarded ad dismissed");
self.rewardedAd = nil;
}
- (void)rewardedAd:(OpAdxRewardedAdBridge *)rewardedAd didFailToDisplayWithError:(OpAdxAdError *)error {
NSLog(@"Rewarded ad failed to show: %@", error.message);
}
- (void)rewardedAd:(OpAdxRewardedAdBridge *)rewardedAd didRewardUserWithItem:(OpAdxRewardItem *)rewardItem {
// rewardItem.type: NSString, rewardItem.amount: NSInteger
NSLog(@"User rewarded: %@ x %ld", rewardItem.type, (long)rewardItem.amount);
}
@endOpAdxRewardedAdDelegate Methods (Objective-C)
| Method | Description |
|---|---|
rewardedAdDidLoad: | Called when the rewarded ad is loaded successfully |
rewardedAd:didFailWithError: | Called when the rewarded ad fails to load |
rewardedAdDidDisplay: | Called when the rewarded ad is displayed |
rewardedAdDidClick: | Called when the rewarded ad is clicked |
rewardedAdDidClose: | Called when the rewarded ad is closed |
rewardedAd:didFailToDisplayWithError: | Called when the rewarded ad fails to show |
rewardedAd:didRewardUserWithItem: | Called when the user earns a reward |
All delegate methods are optional.
5. App Open Ads
App Open ads are shown when users open or switch back to your app.
Swift Implementation
swift
import OpAdxSdk
let kAppOpenPlacementId = "s14496438551808" // Replace with your placement ID
class AppOpenViewController: UIViewController {
private var appOpenAd: OpAdxAppOpenAd?
func loadAppOpenAd() {
destroyAd()
// Create app open ad
appOpenAd = OpAdxAppOpenAd(
placementId: kAppOpenPlacementId,
auctionType: .regular
)
// Create load listener
let loadListener = OpAdxAppOpenAdLoadListenerImp(
onAdLoaded: { [weak self] ad in
print("App open ad loaded")
},
onAdFailedToLoad: { error in
print("App open ad failed to load: \(error.message)")
}
)
// Load ad
appOpenAd?.load(placementId: kAppOpenPlacementId, listener: loadListener)
}
func showAppOpenAd() {
guard let appOpenAd = appOpenAd else { return }
if appOpenAd.isAdInvalidated() {
print("Ad has expired")
loadAppOpenAd()
return
}
// Create interaction listener
let interactionListener = OpAdxAppOpenAdInteractionListenerImp(
onAdClicked: {
print("App open ad clicked")
},
onAdDisplayed: {
print("App open ad displayed")
},
onAdDismissed: { [weak self] in
print("App open ad dismissed")
self?.appOpenAd = nil
},
onAdFailedToShow: { error in
print("App open ad failed to show: \(error.message)")
}
)
// Show ad
appOpenAd.show(on: self, listener: interactionListener)
}
func destroyAd() {
appOpenAd?.destroy()
appOpenAd = nil
}
}Objective-C Implementation
objc
#import <OpAdxSdk/OpAdxSdk.h>
static NSString *const kAppOpenPlacementId = @"s14496438551808"; // Replace with your placement ID
@interface AppOpenViewController () <OpAdxAppOpenAdDelegate>
@property (nonatomic, strong) OpAdxAppOpenAdBridge *appOpenAd;
@end
@implementation AppOpenViewController
- (void)loadAppOpenAd {
[self destroyAd];
// Create app open ad
self.appOpenAd = [[OpAdxAppOpenAdBridge alloc] initWithPlacementId:kAppOpenPlacementId
auctionType:AdAuctionTypeRegular];
self.appOpenAd.delegate = self;
// Load ad
[self.appOpenAd loadAd];
}
- (void)showAppOpenAd {
if (!self.appOpenAd) return;
if (![self.appOpenAd isAdValid]) {
NSLog(@"Ad has expired");
[self loadAppOpenAd];
return;
}
// Show ad
[self.appOpenAd showAdFrom:self];
}
- (void)destroyAd {
self.appOpenAd = nil;
}
#pragma mark - OpAdxAppOpenAdDelegate
- (void)appOpenAdDidLoad:(OpAdxAppOpenAdBridge *)appOpenAd {
NSLog(@"App open ad loaded");
}
- (void)appOpenAd:(OpAdxAppOpenAdBridge *)appOpenAd didFailWithError:(OpAdxAdError *)error {
NSLog(@"App open ad failed to load: %@", error.message);
}
- (void)appOpenAdDidDisplay:(OpAdxAppOpenAdBridge *)appOpenAd {
NSLog(@"App open ad displayed");
}
- (void)appOpenAdDidClick:(OpAdxAppOpenAdBridge *)appOpenAd {
NSLog(@"App open ad clicked");
}
- (void)appOpenAdDidClose:(OpAdxAppOpenAdBridge *)appOpenAd {
NSLog(@"App open ad dismissed");
self.appOpenAd = nil;
}
- (void)appOpenAd:(OpAdxAppOpenAdBridge *)appOpenAd didFailToDisplayWithError:(OpAdxAdError *)error {
NSLog(@"App open ad failed to show: %@", error.message);
}
@endOpAdxAppOpenAdDelegate Methods (Objective-C)
| Method | Description |
|---|---|
appOpenAdDidLoad: | Called when the app open ad is loaded successfully |
appOpenAd:didFailWithError: | Called when the app open ad fails to load |
appOpenAdDidDisplay: | Called when the app open ad is displayed |
appOpenAdDidClick: | Called when the app open ad is clicked |
appOpenAdDidClose: | Called when the app open ad is closed |
appOpenAd:didFailToDisplayWithError: | Called when the app open ad fails to show |
All delegate methods are optional.
Advanced Features
Bidding Support
The Opera Ads SDK supports three bidding modes:
1. Waterfall (Regular)
Standard mediation waterfall based on CPM priorities.
swift
let ad = OpAdxInterstitialAd(placementId: "YOUR_PLACEMENT_ID", auctionType: .regular)2. Client-to-Server (C2S) Bidding
Also known as "In-App Bidding" or "Header Bidding".
swift
// Step 1: Get bid token
let request = BidTokenRequest.Builder(adMediation: .admob)
.placementId("YOUR_PLACEMENT_ID")
.adFormat(.interstitial)
.build()
// Implement BidTokenCallback protocol
class MyBidTokenCallback: BidTokenCallback {
func onSuccess(bidToken: String) {
print("Bid token: \(bidToken)")
// Send token to your mediation platform
}
func onError(error: OpAdxAdError) {
print("Failed to get bid token: \(error.message)")
}
}
OpAdxSDK.getBidToken(request, callback: MyBidTokenCallback())
// Step 2: Load ad with client bidding
let ad = OpAdxInterstitialAd(placementId: "YOUR_PLACEMENT_ID", auctionType: .clientBidding)Objective-C
objective-c
// Step 1: Get bid token
OpAdxBidTokenRequest *request = [[[OpAdxBidTokenRequestBuilder alloc] initWithAdMediation:@"admob"]
placementId:@"YOUR_PLACEMENT_ID"]
adFormat:@"interstitial"]
build];
// Implement OpAdxBidTokenCallback protocol
[OpAdxSDK getBidTokenWithRequest:request callback:self];
// In your callback methods:
- (void)onSuccessWithBidToken:(NSString *)bidToken {
NSLog(@"Bid token: %@", bidToken);
}
- (void)onErrorWithError:(OpAdxAdError *)error {
NSLog(@"Failed: %@", error.message);
}3. Server-to-Server (S2S) Bidding
Bidding handled entirely on the server side.
swift
// Step 1: Get bid token (same as C2S)
// Step 2: Your server participates in the auction
// Step 3: Load ad with bid response
let ad = OpAdxInterstitialAd(placementId: "YOUR_PLACEMENT_ID", auctionType: .serverBidding)
ad.loadRtb(placementId: "YOUR_PLACEMENT_ID", bidResponse: "BID_RESPONSE_FROM_SERVER", listener: listener)Audio Control
Control audio output for video ads:
swift
// Mute all video ads
OpAdxSdkCore.setOpAdxSdkMuted(true)
// Unmute all video ads
OpAdxSdkCore.setOpAdxSdkMuted(false)
// Reset to default (nil = follow device volume)
OpAdxSdkCore.setOpAdxSdkMuted(nil)objective-c
// Objective-C
[OpAdxSdkCore setOpAdxSdkMuted:@YES]; // Mute
[OpAdxSdkCore setOpAdxSdkMuted:@NO]; // Unmute
[OpAdxSdkCore setOpAdxSdkMuted:nil]; // Reset to defaultImportant: Call setOpAdxSdkMuted() before loading ads. It affects all video ad formats.
Server-Side Verification (SSV)
For rewarded ads, configure SSV to prevent reward fraud:
swift
// Configure in your app
let ssvOptions = RewardSsvOptions.Builder()
.userId("user_12345") // Max 100 bytes after URL encoding
.customData("level=5&score=1000") // Max 1KB after URL encoding
.build()
rewardedAd.setRewardSsvOptions(ssvOptions)
// Configure callback URL in Opera Publisher Portal
// Your server will receive a callback when the user earns a rewardSSV Callback Parameters:
user_id: User identifier you providedcustom_data: Custom data you providedreward_type: Reward type (e.g., "coins")reward_amount: Reward amount (e.g., 100)transaction_id: Unique transaction IDsignature: HMAC-SHA256 signature for verification
Privacy & Compliance
COPPA Compliance
If your app is directed at children under 13 (or subject to COPPA):
swift
let config = OpAdxSdkInitConfig.Builder(applicationId: "YOUR_APP_ID")
.coppa(true) // Enable COPPA compliance
.build()COPPA Values:
true: Subject to COPPA (children under 13)false: Not subject to COPPAnil(default): Unspecified
CCPA / US Privacy
Pass the IAB US Privacy String via the SDK init config:
swift
let config = OpAdxSdkInitConfig.Builder(applicationId: "YOUR_APP_ID")
.iOSAppId("YOUR_IOS_APP_ID")
.usPrivacy("1YNN")
.build()GDPR Compliance
The Opera Ads SDK (Vendor ID: 1135) is registered in the IAB TCF Global Vendor List. The SDK automatically reads TCF consent strings (IABTCF_TCString, IABTCF_gdprApplies) from UserDefaults. No additional code is needed if you use a TCF-compliant CMP.
Debug Logging
The Opera Ads SDK includes a comprehensive logging system for development and debugging, helping developers quickly identify and resolve integration issues.
Enable Debug Logs
Swift
swift
// Set log level (do this before SDK initialization)
OpAdxLogger.logLevel = .debug
// Available log levels:
// .none - No logs (recommended for production)
// .error - Errors only
// .warning - Warnings and errors
// .info - Info, warnings, and errors (default)
// .debug - Debug, info, warnings, and errors (recommended for development)
// .verbose - All logs including network request details (for detailed debugging)Objective-C
objective-c
// Set log level (do this before SDK initialization)
OpAdxLogger.logLevel = OpAdxLogLevelDebug;
// Available log levels:
// OpAdxLogLevelNone - No logs
// OpAdxLogLevelError - Errors only
// OpAdxLogLevelWarning - Warnings and errors
// OpAdxLogLevelInfo - Info, warnings, and errors
// OpAdxLogLevelDebug - Debug, info, warnings, and errors
// OpAdxLogLevelVerbose - All logs including network request detailsComplete Log Output Example
With .debug level enabled, you'll see logs throughout the ad lifecycle:
[11:23:45.123] ℹ️ [OpAdx-Init] 📱 Initializing Opera Ads SDK...
[11:23:45.124] ℹ️ [OpAdx-Init] Application ID: pub13423013211200/ep13423013211584/app14170937163904
[11:23:45.125] ℹ️ [OpAdx-Init] iOS App ID: 1444253128
[11:23:45.200] ℹ️ [OpAdx-Init] ✅ SDK initialized successfully
[11:23:45.201] ℹ️ [OpAdx-Init] SDK Version: 2.9.1.20260408
[11:23:50.100] ℹ️ [OpAdx-Banner] 🎯 [Banner] Loading ad - Placement: s14170965187264, Size: 300x250
[11:23:50.101] ℹ️ [OpAdx-AdLoad] 🔄 Loading ad - Placement: s14170965187264, Auction: regular
[11:23:50.102] 🐛 [OpAdx-Network] Request ID: req_1234567890
[11:23:50.103] 🐛 [OpAdx-Network] Format: banner
[11:23:50.104] 🐛 [OpAdx-Network] Auction Type: regular
[11:23:51.200] 🐛 [OpAdx-Network] ✅ Network request succeeded - HTTP 200, Ads: 1
[11:23:51.201] ℹ️ [OpAdx-AdLoad] ✅ Ad loaded successfully - Placement: s14170965187264
[11:23:51.202] 🐛 [OpAdx-AdLoad] Ad Type: banner
[11:23:51.203] 🐛 [OpAdx-AdLoad] Creative ID: cr_9876543210
[11:23:51.204] 🐛 [OpAdx-AdLoad] eCPM: $0.0150
[11:23:51.205] ℹ️ [OpAdx-Banner] ✅ [Banner] Ad loaded successfully
[11:23:55.100] 🐛 [OpAdx-Banner] [Banner] renderAd: Render current banner ad
[11:23:55.500] ℹ️ [OpAdx-Banner] 👁️ Ad impression - Placement: s14170965187264
[11:24:00.100] ℹ️ [OpAdx-Banner] 👆 Ad clicked - Placement: s14170965187264Log Tag System
The SDK uses structured log tags to organize logs by component:
| Log Tag | Description | When It Appears |
|---|---|---|
OpAdx-Init | SDK initialization | During SDK startup |
OpAdx-AdLoad | Ad loading core flow | When loading any ad format |
OpAdx-Network | Network request details | During ad requests and responses |
OpAdx-Banner | Banner ads | Banner lifecycle events |
OpAdx-Interstitial | Interstitial ads | Interstitial lifecycle events |
OpAdx-Rewarded | Rewarded ads | Rewarded ad lifecycle events |
OpAdx-Native | Native ads | Native ad lifecycle events |
OpAdx-AppOpen | App open ads | App open ad lifecycle events |
OpAdx-SKAdNetwork | SKAdNetwork | App Store attribution events |
Error Log Example
When ad loading fails, you'll see detailed error information:
[11:25:00.100] ℹ️ [OpAdx-Banner] 🎯 [Banner] Loading ad - Placement: s14170965187264
[11:25:01.200] ❌ [OpAdx-AdLoad] Ad request failed - Code: 5, Message: NO_FILL
[11:25:01.201] 🐛 [OpAdx-AdLoad] HTTP Status Code: 204
[11:25:01.202] ❌ [OpAdx-Banner] Ad failed to load - Code: 5, Message: NO_FILLCustom Logging
You can also use OpAdxLogger for your own application logs:
swift
// Log custom messages
OpAdxLogger.info("User logged in successfully", tag: "MyApp")
OpAdxLogger.debug("Cache size: 25MB", tag: "MyApp")
OpAdxLogger.warning("Approaching storage limit", tag: "MyApp")
OpAdxLogger.logError("Failed to save file", tag: "MyApp")Production Environment Best Practices
Important Notes:
- ⚠️ Enable DEBUG or VERBOSE logs only in development and testing
- ✅ Use
.infoor.errorlevel in production - ✅ Set log level to
.noneor.errorbefore releasing
swift
#if DEBUG
OpAdxLogger.logLevel = .debug // Development
#else
OpAdxLogger.logLevel = .error // Production
#endifLog Filtering
In Xcode Console, use filtering to quickly locate issues:
- Filter SDK initialization: Search
OpAdx-Init - Filter ad loading: Search
OpAdx-AdLoad - Filter Banner ads: Search
OpAdx-Banner - Filter errors: Search
❌orERROR - Filter success events: Search
✅
Demo Configuration
Use the following test credentials during development:
Application Configuration
swift
let config = OpAdxSdkInitConfig.create(
applicationId: "pub13423013211200/ep13423013211584/app14170937163904",
iOSAppId: "1444253128"
)Test Placement IDs
| Ad Format | Placement ID | Video Support |
|---|---|---|
| Native | s14198263063424 | No |
| Banner | s14170965187264 | No |
| Banner (Video) | s14198605602880 | Yes |
| Interstitial | s14198264979520 | No |
| Interstitial (Video) | s14198603681728 | Yes |
| Rewarded Video | s14198592226752 | Yes |
| Rewarded Interstitial | s14496445187904 | Yes |
| App Open | s14496438551808 | No |
Important Notes:
- Replace placement IDs with your production IDs before releasing
- Never use test credentials in production builds
Error Codes
The SDK returns errors through the OpAdxAdError class.
Load Error Codes
| Code | Name | Description | Resolution |
|---|---|---|---|
| -1 | UNKNOWN_ERROR | Unknown error | Check logs for details |
| 1 | ILLEGAL_API_CALL | Illegal call to SDK API | Ensure SDK is initialized before loading ads |
| 2 | INVALID_PARAMETER | Invalid parameter | Check placement ID and other parameters |
| 3 | ASSETS_ERROR | Ad assets error | Retry loading; contact support if persistent |
| 4 | NETWORK_ERROR | Network connection failed | Check internet connectivity |
| 5 | NO_FILL | No ad available to show | Normal occurrence, try again later |
| 6 | SDK_INITIALIZATION_ERROR | SDK initialization error | Verify Application ID and network access |
Show Error Codes
| Code | Name | Description | Resolution |
|---|---|---|---|
| 101 | SHOW_AD_REUSED | Ad instance has already been shown | Create and load a new ad instance |
| 102 | SHOW_AD_NOT_FOREGROUND | App is not in the foreground | Only show ads when app is active |
| 103 | SHOW_AD_INVALIDATED | Ad has expired or been invalidated | Load a fresh ad |
| 104 | SHOW_AD_START_ACTIVITY_ERROR | Failed to present ad view controller | Ensure the presenting view controller is valid |
Bidding Error Codes
| Code | Name | Description | Resolution |
|---|---|---|---|
| 201 | BID_RESP_DEBUGGING_NOT_ALLOWED | Bid response debugging not allowed | Use production bid responses |
Error Handling Example
swift
let listener = OpAdxBannerAdListenerImp(
onAdLoaded: { bannerAdInfo in
print("Ad loaded successfully")
},
onAdFailedToLoad: { error in
print("Error Code: \(error.code)")
print("Error Message: \(error.message)")
switch error.code {
case OpAdxAdError.ILLEGAL_API_CALL:
// SDK not initialized or illegal API usage
print("Please initialize SDK before loading ads")
case OpAdxAdError.NO_FILL:
// No fill - normal occurrence
print("No ad available, will try again later")
case OpAdxAdError.NETWORK_ERROR:
// Network issues
print("Network issue, retrying in 30 seconds...")
DispatchQueue.main.asyncAfter(deadline: .now() + 30) {
self.loadBannerAd()
}
default:
print("Error: \(error.message)")
}
}
)Best Practices
Ad Loading
- Preload Ads: Load interstitial and rewarded ads in advance
- Check Validity: Always check
isAdInvalidated()before showing - Handle No Fill: Implement retry logic with exponential backoff
- Limit Frequency: Don't load ads too frequently (respect rate limits)
swift
func loadAdWithRetry(attempt: Int = 0) {
guard attempt < 3 else {
print("Max retry attempts reached")
return
}
// Exponential backoff: 1s, 2s, 4s
let delay = pow(2.0, Double(attempt))
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
self.loadAd()
}
}Memory Management
- Destroy Ads: Always call
destroy()when done with an ad - Weak References: Use
[weak self]in closures to avoid retain cycles - Lifecycle Management: Pause/resume banner ads in
viewWillDisappear/viewWillAppear
swift
// Destroy banner when view controller is deallocated
deinit {
bannerAdView?.destroy()
bannerAdView = nil
}
// Pause/resume banner ads
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
bannerAdView?.pause()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
bannerAdView?.resume()
}User Experience
- Natural Breaks: Show interstitials at natural transition points
- Clear Rewards: Clearly communicate rewards before showing rewarded ads
- Loading States: Show loading indicators while ads load
- Fallback Content: Have alternative content if no ad is available
swift
func showInterstitialAtNaturalBreak() {
// Good: After level completion
// Good: After user action (e.g., closing settings)
// Bad: Mid-gameplay
// Bad: During active user interaction
if interstitialAd != nil && !interstitialAd!.isAdInvalidated() {
showInterstitialAd()
} else {
// Fallback: Continue without ad
proceedToNextScreen()
}
}Performance
- Main Thread: All SDK APIs must be called on the main thread
- Background Loading: SDK handles network calls asynchronously
- Resource Cleanup: Remove ads from view hierarchy when destroyed
swift
// ✅ Correct: Call on main thread
DispatchQueue.main.async {
self.loadBannerAd()
}
// ❌ Wrong: Don't call on background thread
DispatchQueue.global().async {
self.loadBannerAd() // May cause crashes
}Troubleshooting
Issue: Ads Not Loading
Symptoms: onAdFailedToLoad called with NO_FILL error
Solutions:
- Check internet connectivity
- Verify placement ID is correct
- Check if ad inventory is available for your region
- Review error logs for specific error codes
Issue: SDK Initialization Failed
Symptoms: SDK initialization callback returns error
Solutions:
- Verify Application ID format:
pub{}/ep{}/app{} - Check iOS App ID is a valid numeric string
- Ensure SDK is initialized before loading ads
- Check debug logs for specific error message
Issue: Ads Not Showing
Symptoms: Ad loads successfully but doesn't display
Solutions:
- Check if ad has expired:
isAdInvalidated() - Ensure view controller is presented (not nil)
- Verify ad view is added to view hierarchy
- Check Auto Layout constraints
- Ensure main thread is used for UI operations
Issue: Crash on Ad Load
Solutions:
- Ensure SDK is initialized before loading ads
- Check all APIs are called on main thread
- Verify placement ID format
- Update to latest SDK version
- Enable debug logging and check crash logs
Issue: Rewarded Ads Not Granting Rewards
Solutions:
- Check
onUserRewardedcallback is implemented - Verify SSV configuration (if using server-side verification)
- Ensure user watches ad completely
- Check reward logic implementation
- Review SSV callback logs on your server
Migration Guide
From v2.8.x to v2.9.x
Breaking Changes:
- None
New Features:
- Enhanced debug logging system
- Improved bidding support
- SKAdNetwork 4.0 support
Recommended Actions:
- Update pod version to
~> 2.9.1 - Enable new logging system during development
- Test all ad formats thoroughly
From v2.6.x to v2.7.x
Breaking Changes:
- Initialization callback signatures changed
Migration Steps:
swift
// Old (v2.6.x)
OpAdxSdkCore.shared.initialize(initConfig: config)
// New (v2.7.x+)
OpAdxSDK.initialize(
withConfig: config,
onSuccess: {
print("SDK initialized")
},
onError: { error in
print("Init failed: \(error)")
}
)Support & Resources
Documentation
- Integration Guide: This document
- Release Notes: Release Notes
- Client Bidding: Client Bidding Guide
- Server Bidding: Server Bidding Guide
- Mediation: Mediation Guide
Contact
- Publisher Portal: https://publisher.opera.com
Appendix
Minimum SDK Requirements
| Component | Minimum Version |
|---|---|
| iOS | 13.0 |
| Xcode | 14.0 |
| Swift | 5.0 |
| CocoaPods | 1.10.0 |
Third-Party Dependencies
The SDK has no external pod dependencies.
SKAdNetwork Support
The SDK supports SKAdNetwork for ad attribution as a Source App. The SDK automatically handles startImpression / endImpression calls for fullscreen ads (Interstitial, Rewarded, App Open) and Native ads. For Banner ads, attribution is handled via SKOverlay presentation rather than the startImpression / endImpression lifecycle, since banners are continuously displayed views without a distinct dismiss event.
1. Add SKAdNetwork ID to Info.plist (Required)
You must add Opera's SKAdNetworkIdentifier to your app's Info.plist. Without this, the system will silently ignore all attribution for Opera's ad network.
xml
<key>SKAdNetworkItems</key>
<array>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>a2p9lx4jpn.skadnetwork</string>
</dict>
</array>Note: If you are already using other ad networks, simply add Opera's identifier to your existing
SKAdNetworkItemsarray.
2. Enable SKAdNetwork in Code (Optional)
SKAdNetwork is enabled by default. You can configure it during initialization:
swift
// SKAdNetwork is enabled by default, disable if needed
OpAdxSDK.setSKAdNetworkEnabled(true)
// Enable debug logging for development
OpAdxSDK.setSKAdNetworkDebugLogEnabled(true)
// Register app for attribution (call once at app launch)
OpAdxSKAdNetworkManager.shared.registerApp()3. SKOverlay Configuration (Optional)
The SDK can display SKOverlay (in-app App Store overlay) for supported ads:
swift
// Enable/disable SKOverlay (default: true)
OpAdxSKAdNetworkManager.shared.useSKOverlay = true
// Display strategy: .auto (default), .onImpression, .onClick
OpAdxSKAdNetworkManager.shared.overlayDisplayStrategy = .auto- auto: Fullscreen ads (interstitial, rewarded, app open) show overlay on impression; non-fullscreen ads (banner, native) show on click
- onImpression: Always show overlay when ad is displayed
- onClick: Only show overlay when user clicks the ad
Document Version: 2.9.1 Last Updated: 2026-04-28 SDK Version: 2.9.1
