iOS Integration
Introduction
Smaato has developed a brand new SDK, built to support topics such as in-app header bidding and other advanced formats.
For more details about Smaato’s NextGen SDK, please contact your Smaato Account Manager.
SPX Setup
- Ask your Smaato Account Manager to enable Unified Bidding for your SPX account.
- After enablement, you’ll see a new Header Bidding Configuration in the SPX dropdown.
- In SPX, create a new Adspace and a new Smaato Exchange Line Item to be used by the NextGen SDK.
- Best practice: use a distinct Adspace for Unified Bidding to avoid collisions. Otherwise, the NextGen SDK can’t guarantee the served creative matches the originally requested/cached creative.
Please Note:
Unified Bidding revenues are associated with this Adspace.
Important Note About Fullscreen Adspaces
Only Interstitial Multi-Ad Format is currently compatible for Fullscreen Adspaces with the NextGen SDK.
-
To monetize fullscreen Adspaces, select Interstitial (Display & Video) in SPX. Other fullscreen options are not supported at this time.
-
If you don’t see Interstitial (Display & Video) in the Ad Format dropdown, contact your Smaato Account Manager.
-
When creating Fullscreen Adspaces in SPX, choose Interstitial (Display & Video) as the Ad Format. (Figure 1)
-
For Creative Type you have three options (Figure 2):
- Display Only – Rich Media ads
- Video Only – Video ads
- Display and Video – Either Rich Media or Video

Figure 1:Ad Format dropdown selection

Figure 2: Creative Type dropdown selections
Unified Bidding Configuration
The Unified Bidding Configuration allows publishers to define parameters used by the NextGen SDK.
Introduction to Price Granularity
- Unified Bidding collects bids and passes the highest price to your primary ad server in the ad call. Create one line item per price point in your primary ad server and use key-value targeting to match the bid price from the NextGen SDK.
- To avoid creating line items for every cent ($0.01 … $20.00), start with $0.10 increments (e.g., $1.04 rounds down to $1.00). You can later increase granularity in SPX to improve yield.
- Reflect any price granularity changes in your ad server setup. The SDK picks up granularity modifications within 24 hours.
Timeouts
- For each impression opportunity, Unified Bidding has a limited time to receive a bid. Bids arriving after the round-trip timeout are omitted.
- Default timeout: 1,000 ms (modifiable in SPX; SDK picks up the change within 24 hours).
Note:
Overly restrictive timeouts negatively impact monetization. Start with 1,000–1,200 ms.
Bid Adjustment
- Bid Adjustment lets you adjust the bid before it’s added as a key-value in the ad call (e.g., convert gross → net).
- Default is 100%, but you can decrease or increase as needed.

Examples:
| Bid Adjustment % Value | Bid Price (before adjustment) | Bid Price (after adjustment) |
|---|---|---|
| 100% | $1.00 | $1.00 |
| 70% | $1.00 | $0.70 |
| 120% | $1.00 | $1.20 |
GAM Setup Process
- For each price point configured in SPX, create a matching line item in GAM.
- Add a Dynamic Key called
smaub(no value) under Inventory → Key-Values. See Google’s guide: https://support.google.com/admanager/answer/9796369
GAM Dashboard Setup
- Go to the GAM Dashboard.
- Click Create Mediation Group.
- Select Ad format as needed: Banner, Interstitial, Native, Rewarded.
- Set desired parameters in the next tab.
- Under Add Ad Unit, select the ad unit targeted for mediation.
- Under Ad sources, click ADD CUSTOM EVENT:
- Provide Label and desired eCPM.
- Under Configure ad units, provide class names:
- Banner:
SMAAdMobSmaatoBannerAdapter - Interstitial:
SMAAdMobSmaatoInterstitialAdapter - Rewarded Video:
SMAAdMobSmaatoRewardedVideoAdapter - Native:
SMAAdMobSmaatoNativeAdapter
- Banner:
- Pass parameter for SPX Adspace ID:
adSpaceId=<YOUR_SPX_ADSPACE_ID>
- Set eCPM to the price you want to target (e.g., $0.10).
- Do not add day/time targeting.
- Do not add frequency capping.
In Custom Targeting → Key-Values, target key smaub and enter a value for each line item in the form smaato_cpm:<price>.
Examples:
- $0.10 →
smaato_cpm:0.10 - $1.30 →
smaato_cpm:1.30 - $20.00 →
smaato_cpm:20.00
Integrating an iOS App
Prerequisites
- Xcode 10.2.1+
- CocoaPods — https://cocoapods.org/
Choose Ad Formats
The SDK is modular. Link required frameworks for desired ad formats.
Framework combinations:
| Framework | Banner / Image + Rich Media | Interstitial / Image + Rich Media | Interstitial / Video | Interstitial / Image + Rich Media + Video | Native |
|---|---|---|---|---|---|
SmaatoSDKCore.framework¹ | X | X | X | X | X |
SmaatoSDKOpenMeasurement.framework¹ | X | X | X | X | X |
SmaatoSDKBanner.framework | X | ||||
SmaatoSDKNative.framework | X | ||||
SmaatoSDKInterstitial.framework | X | X | X | ||
SmaatoSDKRichMedia.framework | X | X | X | ||
SmaatoSDKVideo.framework | X | X | |||
SmaatoSDKUnifiedBidding.framework² | X* | X* | X* | X* | X* |
Note:
- ¹ Mandatory dependency in any configuration.
- ² Optional dependency for revenue maximization (contact your Account Manager).
Smaato iOS SDK Setup and Initialization
Installation Requirements
- Integrate AdMob iOS SDK: https://developers.google.com/admob/ios/quick-start
- Integrate CocoaPods: https://cocoapods.org/
SDK Integration
With the modular structure of Smaato’s NextGen SDK, you can select different integration options. The following are configuration examples for your project Podfile:
Banner (with Rich Media support)
pod 'smaato-ios-sdk/Banner'
pod 'smaato-ios-sdk/Modules/UnifiedBidding'
pod 'smaato-ios-sdk-mediation-admob/Banner'
Interstitial (with Rich Media & Video)
pod 'smaato-ios-sdk/Interstitial'
pod 'smaato-ios-sdk/Modules/UnifiedBidding'
pod 'smaato-ios-sdk-mediation-admob/Interstitial'
Interstitial (Rich Media & Image only; no Video)
pod 'smaato-ios-sdk/Modules/Interstitial'
pod 'smaato-ios-sdk/Modules/RichMedia'
pod 'smaato-ios-sdk/Modules/UnifiedBidding'
pod 'smaato-ios-sdk-mediation-admob/Interstitial'
Now you can run pod install
SDK Initialization Using AppDelegate Class
In the AppDelegate class, import SmaatoSDKCore module and configure SDK in “application:didFinishLaunchingWithOptions:“. Smaato’s Unified Bidding module will automatically be enabled for the publisher that is set on SDK initialization if the module has previously been integrated.
// AppDelegate.m
#import "AppDelegate.h"
@import SmaatoSDKCore;
@import SmaatoSDKUnifiedBidding;
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// initialize SDK first!
SMAConfiguration *config = [[SMAConfiguration alloc] initWithpublisherId:@”<PUBLISHER_ID>”];
config.httpsOnly = NO; // allow both HTTPS & HTTP traffic
config.logLevel = kSMALogLevelError; // log errors only
config.maxAdContentRating = kSMAMaxAdContentRatingUndefined; // ads content restriction based on age
[SmaatoSDK initSDKWithConfig:config];
SmaatoSDK.gpsEnabled = YES; // allow the Smaato SDK to automatically get the user's location and put it inside the ad request
return YES;
}
@end
// AppDelegate.swift
import UIKit
import SmaatoSDKCore
import SmaatoSDKUnifiedBidding
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// initialize SDK first!
guard let config = SMAConfiguration(publisherId:”<PUBLISHER_ID>”) else {
fatalError(“SDK config is nil”)
}
config.httpsOnly = false // allow both HTTPS & HTTP traffic
config.logLevel = .error // log errors only
config.maxAdContentRating = .undefined // ads content restriction based on age
SmaatoSDK.initSDK(withConfig: config)
SmaatoSDK.gpsEnabled = true // allow the Smaato SDK to automatically get the user's location and put it inside the ad request
return true
}
}
Please visit: https://developers.google.com/ad-manager/mobile-ads-sdk/ios/quick-start for GAM setup.
Location Update
Optional: Use the instance of CLLocationManager class to configure, start, and stop the Core Location services. If you provide device location data once or periodically, the geo-targeted ads are delivered. Such ads have higher conversions and click rate.
/** CLLocationManagerDelegate method */
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
CLLocation *userLocation = locations.lastObject;
if (userLocation) {
SmaatoSDK.userLocation = [[SMALocation alloc] initWithLatitude:userLocation.coordinate.latitude
longitude:userLocation.coordinate.longitude
horizontalAccuracy:userLocation.horizontalAccuracy
timestamp:userLocation.timestamp];
}
}
Class which conforms to CLLocationManagerDelegate protocol
/** CLLocationManagerDelegate method */
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let userLocation = locations.last else {
return
}
SmaatoSDK.userLocation = SMALocation(latitude:userLocation.coordinate.latitude,
longitude:userLocation.coordinate.longitude,
horizontalAccuracy:userLocation.horizontalAccuracy,
timestamp:userLocation.timestamp)
}
Smaato SDK Integration
Smaato SDK supports several standard banner dimensions, which should be used for Prebid request. They are declared in SMAUbBannerSize enum. Use appropriate value as parameter in prebidBannerForAdSpaceId() method call.
Banner sizes (public header of Smaato Unified Bidding framework).
/** Banner sizes supported in the SDK */
typedef NS_ENUM(NSUInteger, SMAUbBannerSize) {
/** XXLarge (320x50) banner*/
kSMAUbBannerSizeXXLarge_320x50 = 0,
/** Medium Rectangle (300*250) banner */
kSMAUbBannerSizeMediumRectangle_300x250,
/** Skyscraper (120x600) banner*/
kSMAUbBannerSizeSkyscraper_120x600,
/** Leaderboard (728x90) banner*/
kSMAUbBannerSizeLeaderboard_728x90
};
Prebid request (public header of Smaato Unified Bidding framework)
@interface SmaatoSDK (UnifiedBidding)
/**
The method sends prebid request for Banner Smaato ads
@param adSpaceId AdspaceId identifier assigned by Smaato. Unified Bidding support should be enabled for this AdspaceId in Smaato SPX.
Must not be \c nil
@param bannerSize The banner size to be returned. see \c SMAUbBannerSize
@param completion Callback is invoked, when prebid response processing has been finished.
`bid` or `error` values reflect state of Prebid request. Must not be \c nil.
*/
+ (void)prebidBannerForAdSpaceId:(NSString *_Nonnull)adSpaceId
bannerSize:(SMAUbBannerSize)bannerSize
completion:(void (^_Nonnull)(SMAUbBid *_Nullable bid, NSError *_Nullable error))completion;
/**
The method sends prebid request for Interstitial Smaato ads
@param adSpaceId AdspaceId identifier assigned by Smaato. Unified Bidding support should be enabled for this AdspaceId in Smaato SPX.
Must not be \c nil
@param completion Callback is invoked, when prebid response processing has been finished.
`bid` or `error` values reflect state of Prebid request. Must not be \c nil.
*/
+ (void)prebidInterstitialForAdSpaceId:(NSString *_Nonnull)adSpaceId
completion:(void (^_Nonnull)(SMAUbBid *_Nullable bid, NSError *_Nullable error))completion;
/**
The method sends prebid request for Rewarded Interstitial Smaato ads
@param adSpaceId AdspaceId identifier assigned by Smaato. Unified Bidding support should be enabled for this AdspaceId in Smaato SPX.
Must not be \c nil
@param completion Callback is invoked, when prebid response processing has been finished.
`bid` or `error` values reflect state of Prebid request. Must not be \c nil.
*/
+ (void)prebidRewardedInterstitialForAdSpaceId:(NSString *_Nonnull)adSpaceId
completion:(void (^_Nonnull)(SMAUbBid *_Nullable bid, NSError *_Nullable error))completion;
/**
The method sends prebid request for Outstream Smaato ads
@param adSpaceId AdspaceId identifier assigned by Smaato. Unified Bidding support should be enabled for this AdspaceId in Smaato SPX.
Must not be \c nil
@param bannerSize The banner size to be returned. see \c SMAUbBannerSize. Must not be \c nil
@param completion Callback is invoked, when prebid response processing has been finished.
`bid` or `error` values reflect state of Prebid request. Must not be \c nil.
*/
+ (void)prebidOutstreamForAdSpaceId:(NSString *_Nonnull)adSpaceId
bannerSize:(SMAUbBannerSize)bannerSize
completion:(void (^_Nonnull)(SMAUbBid *_Nullable, NSError *_Nullable))completion;
/**
The method sends prebid request for Native Smaato ads
@param adSpaceId AdspaceId identifier assigned by Smaato. Unified Bidding support should be enabled for this AdspaceId in Smaato SPX.
Must not be \c nil
@param completion Callback is invoked, when prebid response processing has been finished.
`bid` or `error` values reflect state of Prebid request. Must not be \c nil.
*/
+ (void)prebidNativeForAdSpaceId:(NSString *_Nonnull)adSpaceId completion:(void (^_Nonnull)(SMAUbBid *_Nullable, NSError *_Nullable))completion;
@end
Prebid response for publisher needs (public header of Smaato Unified Bidding framework)
@interface SMAUbBid: NSObject
/**
Adjusted bid price on the base of the chosen granularity of ad displaying
*/
@property (nonatomic, readonly) CGFloat bidPrice;
/**
Optional helper method builds keyword for LineItem in a format "smaato_cpm:X.XX",
where X.XX is adjusted bid price for LineItem.
*/
@property (nonatomic, copy, readonly, nonnull) NSString *targetPrebidKeyword;
/**
Optional helper method provides metadata dictionary that allows to fetch related ad creative in case
of bid prices auction win.
*/
@property (nonatomic, copy, readonly, nonnull) NSDictionary *metaData;
+ (null_unspecified instancetype)new NS_UNAVAILABLE;
- (null_unspecified instancetype)init NS_UNAVAILABLE;
@end
Example Ad Requests
Unified Bidding module initialization without any changes:
In the AppDelegate class, import the SmaatoSDKCore module and configure SDK in “application:didFinishLaunchingWithOptions:“. The Smaato Unified Bidding module will automatically be enabled for the publisher ID used for SDK initialization if the module has previously been integrated.
Banner Request (320×50)
To add Smaato Unified Bidding to your AdMob Banner, follow these steps:
- First, find the line of code where you create an
GAMBannerViewbanner instance to add Smaato Unified Bidding. - Next, add the [
SmaatoSDK prebidBannerForAdSpaceId:] method call to your code in the same way shown in the examples below. ThebannerSizeparameter should match supported Smaato banner dimensions: standard size banner (320×50), medium rectangle size banner (300×250), leaderboard size banner (728×90), skyscraper banner size (120×600). - Then, move the loadAd method call to the completion callback of the prebidBannerForAdSpaceId method and use Prebid data from SMAUbBid bid* instance to build correct targeting string for the Smaato Line Item (which you have created earlier via the GAM Dashboard) and save unique Prebid banner creative identifier to be able to fetch exact banner creative from cache in case of auction win. Finally, pass the UB bidKeyword string in Key-value form inside GAMRequest and call loadAd.
Important Note:
It can be possible that a Smaato Unified Bidding bid price is higher than the maximum price point of the line-items created in the GAM Dashboard. In this scenario, the bid will not match any line-item and a profitable bid will have been wasted. Smaato provides a snippet of code to allow you to round down the bid price to the maximum price point. To do this, you need to declare the maximum price point (
maxPricewithin the code snippet below). Then the value will be used to match the GAM line-item to allow for all profitable bids to not be wasted.
GAM Specific
var bannerView = GAMBannerView(adSize: kGADAdSizeBanner)
bannerView.adUnitID = "YOUR_GAM_AD_UNIT_ID"
bannerView.rootViewController = self
bannerView.delegate = self
SmaatoSDK.prebidBanner(forAdSpaceId: "SMAATO_ADSPACE_ID",
bannerSize: .xxLarge_320x50) {(bid: SMAUbBid?, error: Error?) in
if let smaatoBid = bid {
// Let's assume this is the max price of your line items (you will want to change this float to yours)
let maxPrice : CGFloat = 0.1
let bidKeyword : String
// Helper to format bidKeyword if the received bid price is greater than max price. In this case, just add smaato_cpm prefix to the maxPrice (formatted value to the required fraction digits).
if smaatoBid.bidPrice > maxPrice {
bidKeyword = String(format: "smaato_cpm:%.2f", maxPrice)
} else {
bidKeyword = smaatoBid.targetPrebidKeyword
}
let kvpRequest = GAMRequest()
let ubKVP = [
"smaub": bidKeyword // make sure you add "smaub" as a Dynamic Key under Inventory >> Key-Values inside of GAM (no value as you will pass that here)
]
kvpRequest.customTargeting = ubKVP
bannerView.load(kvpRequest)
}
}
GAMBannerView *bannerView = [[GAMBannerView alloc] initWithAdSize:GADAdSizeBanner];
bannerView.adUnitID = @"YOUR_GAM_AD_UNIT_ID";
bannerView.rootViewController = self;
bannerView.delegate = self;
[SmaatoSDK prebidBannerForAdSpaceId:@"SMAATO_ADSPACE_ID" bannerSize:kSMAUbBannerSizeXXLarge_320x50 completion:^(SMAUbBid * _Nullable bid, NSError * _Nullable error) {
if (bid) {
// Let's assume this is the max price of your line items (you will want to change this float to yours)
CGFloat maxPrice = 0.1;
NSString *bidKeyword;
// Helper to format bidKeyword if the received bid price is greater than max price. In this case, just add smaato_cpm prefix to the maxPrice (formatted value to the required fraction digits).
if (bid.bidPrice > maxPrice) {
bidKeyword = [NSString stringWithFormat:@"smaato_cpm:%.2f", maxPrice];
} else {
bidKeyword = bid.targetPrebidKeyword;
}
GAMRequest *kvpRequest = [[GAMRequest alloc] init];
NSDictionary<NSString *, NSString *> *ubKVP = [[NSDictionary alloc] initWithObjectsAndKeys:@"smaub", bidKeyword, nil]; // make sure you add "smaub" as a Dynamic Key under Inventory >> Key-Values inside of GAM (no value as you will pass that here)
kvpRequest.customTargeting = ubKVP;
[bannerView loadRequest:kvpRequest];
}
}];
Generic
var bannerView = SMABannerView()
SmaatoSDK.prebidBanner(forAdSpaceId: "SMAATO_ADSPACE_ID",
bannerSize: .mediumRectangle_300x250) { [unowned self] (ubBid, error) in
guard let bid = ubBid ,
let bidId = bid.metaData["smaato_ubid"] as? String else {
return
}
let requestParams = SMAAdRequestParams()
requestParams.ubUniqueId = bidId
bannerView.delegate = self
bannerView.load(withAdSpaceId: "SMAATO_ADSPACE_ID",
adSize: .mediumRectangle_300x250,
requestParams: requestParams)
}
SMABannerView *bannerView = [[SMABannerView alloc]init];
[SmaatoSDK prebidBannerForAdSpaceId:@"SMAATO_ADSPACE_ID" bannerSize:kSMAUbBannerSizeMediumRectangle_300x250 completion:^(SMAUbBid * _Nullable bid, NSError * _Nullable error) {
if (bid && bid.metaData[@"smaato_ubid"]) {
NSString *ubId = bid.metaData[@"smaato_ubid"];
SMAAdRequestParams *requestParam = [[SMAAdRequestParams alloc] init];
requestParam.ubUniqueId = ubId;
bannerView.delegate = self;
[bannerView loadWithAdSpaceId:@"SMAATO_ADSPACE_ID" adSize:kSMABannerAdSizeMediumRectangle_300x250 requestParams:requestParam];
} else {
return;
}
}];
Important Note:
To support Smaato’s Unified Bidding solution, a refresh of GAM banner ads should be done explicitly on the publisher’s side. Otherwise, the winner of the first round will request and display the ads during the whole session (while the GAM banner is on the screen). Please disable auto updater(if any) and use the delegate callbacks provided by GAM, clear keywords in the GAM request(if any) and make another request as in Step 3 to get new bids. This is applicable to all Unified Bidding providers.
Interstitial request
To add Smaato Unified Bidding to your Interstitial, follow these steps:
- First, find the line of code where you call the
GAMInterstitialAdinstance to add Smaato Unified Bidding. - Next, add the [
SmaatoSDK prebidInterstitialForAdSpaceId:] method call to your code in the same way shown in the examples below. - Then, move the
loadAdmethod call to the completion callback of theprebidInterstitialForAdSpaceIdmethod and use Prebid data from theSMAUbBid*bid instance to build the correct targeting string for the Smaato Line Item (which you have created earlier via the GAM Dashboard) and save unique Prebid interstitial creative identifier to be able to fetch exact interstitial creative from cache in case of auction win. Finally, pass the UB bidKeyword string in Key-value form inside GAMRequest and callloadAd.
GAM Specific
var interstitial: GAMInterstitialAd?
SmaatoSDK.prebidInterstitial(forAdSpaceId: "SMAATO_ADSPACE_ID") { (bid: SMAUbBid?, error: Error?) in
if let smaatoBid = bid {
// Let's assume this is the max price of your line items (you will want to change this float to yours)
let maxPrice : CGFloat = 0.1
let bidKeyword : String
if smaatoBid.bidPrice > maxPrice {
bidKeyword = String(format: "smaato_cpm:%.2f", maxPrice)
} else {
bidKeyword = smaatoBid.targetPrebidKeyword
}
let kvpRequest = GAMRequest()
let ubKVP = [
"smaub": bidKeyword // make sure you add "smaub" as a Dynamic Key under Inventory >> Key-Values inside of GAM (no value as you will pass that here)
]
kvpRequest.customTargeting = ubKVP
GAMInterstitialAd.load(withAdManagerAdUnitID:"YOUR_GAM_AD_UNIT_ID",
request: kvpRequest,
completionHandler: { [self] ad, error in
if let error = error {
print("Failed to load interstitial ad with error: \(error.localizedDescription)")
return
}
interstitial = ad
interstitial?.fullScreenContentDelegate = self
}
)
}
}
__block GAMInterstitialAd *interstitial;
[SmaatoSDK prebidInterstitialForAdSpaceId:@"SMAATO_ADSPACE_ID" completion:^(SMAUbBid * _Nullable bid, NSError * _Nullable error) {
if (bid) {
// Let's assume this is the max price of your line items (you will want to change this float to yours)
CGFloat maxPrice = 0.1;
NSString *bidKeyword;
// Helper to format bidKeyword if the received bid price is greater than max price. In this case, just add smaato_cpm prefix to the maxPrice (formatted value to the required fraction digits).
if (bid.bidPrice > maxPrice) {
bidKeyword = [NSString stringWithFormat:@"smaato_cpm:%.2f", maxPrice];
} else {
bidKeyword = bid.targetPrebidKeyword;
}
GAMRequest *kvpRequest = [[GAMRequest alloc] init];
NSDictionary<NSString *, NSString *> *ubKVP = [[NSDictionary alloc] initWithObjectsAndKeys:@"smaub", bidKeyword, nil]; // make sure you add "smaub" as a Dynamic Key under Inventory >> Key-Values inside of GAM (no value as you will pass that here)
kvpRequest.customTargeting = ubKVP;
[GAMInterstitialAd loadWithAdManagerAdUnitID:@"YOUR_GAM_AD_UNIT_ID" request:kvpRequest completionHandler:^(GAMInterstitialAd * _Nullable interstitialAd, NSError * _Nullable error) {
if (error) {
NSLog(@"Failed to load interstitial ad with error: \(error.localizedDescription)");
return;
}
interstitial = interstitialAd;
interstitial.fullScreenContentDelegate = self;
}];
}
}];
Generic
SmaatoSDK.prebidInterstitial(forAdSpaceId: "SMAATO_ADSPACE_ID") { [unowned self] (ubBid, error) in
guard let bid = ubBid ,
let bidId = bid.metaData["smaato_ubid"] as? String else {
return
}
let requestParams = SMAAdRequestParams()
requestParams.ubUniqueId = bidId
SmaatoSDK.loadInterstitial(forAdSpaceId: "SMAATO_ADSPACE_ID",
delegate: self,
requestParams: requestParams)
}
[SmaatoSDK prebidInterstitialForAdSpaceId:@"SMAATO_ADSPACE_ID"
completion:^(SMAUbBid *_Nullable bid, NSError *_Nullable error) {
if (bid && bid.metaData[@"smaato_ubid"]) {
NSString *ubId = bid.metaData[@"smaato_ubid"];
SMAAdRequestParams *requestParam = [[SMAAdRequestParams alloc] init];
requestParam.ubUniqueId = ubId;
[SmaatoSDK loadInterstitialForAdSpaceId:@"SMAATO_ADSPACE_ID" delegate:self requestParams:requestParam];
} else {
return;
}
}];
Rewarded Video request
To add Smaato Unified Bidding to your Rewarded Video Ad, you need to follow these steps:
- First, find the line of code where you load the GAM
RewardedAdto add Smaato Unified Bidding. - Next, add the [
SmaatoSDK prebidRewardedInterstitialForAdSpaceId:] method call to your code the same way it’s added in the examples below. - Then, move load method call to the completion callback of
prebidRewardedInterstitialForAdSpaceIdmethod and use Prebid data fromSMAUbBid*bid instance to build correct targeting string for Smaato LineItem (which you have created early via GAM Dashboard). - Finally, pass the UB bidKeyword string in Key-value form inside GAMRequest and call
loadAd.
GAM Specific
var rewardedAd: GADRewardedAd?
SmaatoSDK.prebidRewardedInterstitial(forAdSpaceId: "SMAATO_ADSPACE_ID") { (bid: SMAUbBid?, error: Error?) in
if let smaatoBid = bid {
// Let's assume this is the max price of your line items (you will want to change this float to yours)
let maxPrice : CGFloat = 0.1
let bidKeyword : String
if smaatoBid.bidPrice > maxPrice {
bidKeyword = String(format: "smaato_cpm:%.2f", maxPrice)
} else {
bidKeyword = smaatoBid.targetPrebidKeyword
}
let kvpRequest = GAMRequest()
let ubKVP = [
"smaub": bidKeyword // make sure you add "smaub" as a Dynamic Key under Inventory >> Key-Values inside of GAM (no value as you will pass that here)
]
kvpRequest.customTargeting = ubKVP
GADRewardedAd.load(withAdUnitID:"YOUR_GAM_AD_UNIT_ID",
request: kvpRequest,
completionHandler: { [self] ad, error in
if let error = error {
print("Failed to load rewarded ad with error: \(error.localizedDescription)")
return
}
rewardedAd = ad
rewardedAd?.fullScreenContentDelegate = self
}
)
}
}
__block GADRewardedAd *rewardedInterstitialAd;
[SmaatoSDK prebidRewardedInterstitialForAdSpaceId:@"SMAATO_ADSPACE_ID" completion:^(SMAUbBid * _Nullable bid, NSError * _Nullable error) {
if (bid) {
// Let's assume this is the max price of your line items (you will want to change this float to yours)
CGFloat maxPrice = 0.1;
NSString *bidKeyword;
// Helper to format bidKeyword if the received bid price is greater than max price. In this case, just add smaato_cpm prefix to the maxPrice (formatted value to the required fraction digits).
if (bid.bidPrice > maxPrice) {
bidKeyword = [NSString stringWithFormat:@"smaato_cpm:%.2f", maxPrice];
} else {
bidKeyword = bid.targetPrebidKeyword;
}
GAMRequest *kvpRequest = [[GAMRequest alloc] init];
NSDictionary<NSString *, NSString *> *ubKVP = [[NSDictionary alloc] initWithObjectsAndKeys:@"smaub", bidKeyword, nil]; // make sure you add "smaub" as a Dynamic Key under Inventory >> Key-Values inside of GAM (no value as you will pass that here)
kvpRequest.customTargeting = ubKVP;
[GADRewardedAd loadWithAdUnitID:@"YOUR_GAM_AD_UNIT_ID" request:kvpRequest completionHandler:^(GADRewardedAd * _Nullable rewardedAd, NSError * _Nullable error) {
if (error) {
NSLog(@"Failed to load interstitial ad with error: \(error.localizedDescription)");
return;
}
rewardedInterstitialAd = rewardedAd;
rewardedInterstitialAd.fullScreenContentDelegate = self;
}];
}
}];
Generic
SmaatoSDK.prebidRewardedInterstitial(forAdSpaceId: "SMAATO_ADSPACE_ID") { [unowned self] (ubBid, error) in
guard let bid = ubBid,
let bidId = bid.metaData["smaato_ubid"] as? String else {
return
}
let requestParams = SMAAdRequestParams()
requestParams.ubUniqueId = bidId
SmaatoSDK.loadRewardedInterstitial(forAdSpaceId: "SMAATO_ADSPACE_ID",
delegate: self,
requestParams: requestParams)
}
[SmaatoSDK prebidRewardedInterstitialForAdSpaceId:@"SMAATO_ADSPACE_ID"
completion:^(SMAUbBid *_Nullable bid, NSError *_Nullable error) {
if (bid && bid.metaData[@"smaato_ubid"]) {
NSString *ubId = bid.metaData[@"smaato_ubid"];
SMAAdRequestParams *requestParam = [[SMAAdRequestParams alloc] init];
requestParam.ubUniqueId = ubId;
[SmaatoSDK loadRewardedInterstitialForAdSpaceId:@"SMAATO_ADSPACE_ID" delegate:self requestParams:requestParam];
} else {
return;
}
}];
Native Ad request
To add Smaato Unified Bidding to your Native Ad, follow these steps:
- Add the
UnifiedBidding.prebidNativemethod call to your code in the same way shown in the examples below. - Then, move the load method call to the PrebidListener callback method and use Prebid data from SMAUbBid *bid instance to build correct targeting string for Smaato Line Item (which you have created early via GAM Dashboard).
- Finally, pass the UB bidKeyword string in Key-value form inside GAMRequest and call loadAd.
GAM Specific
SmaatoSDK.prebidNative(forAdSpaceId: "SMAATO_ADSPACE_ID")
{ [weak self] bid, error in
if let smaatoBid = bid {
// Let's assume this is the max price of your line items (you will want to change this float to yours)
let maxPrice : CGFloat = 0.1
let bidKeyword : String
// Helper to format bidKeyword if the received bid price is greater than max price. In this case, just add smaato_cpm prefix to the maxPrice (formatted value to the required fraction digits).
if smaatoBid.bidPrice > maxPrice {
bidKeyword = String(format: "smaato_cpm:%.2f", maxPrice)
} else {
bidKeyword = smaatoBid.targetPrebidKeyword
}
let kvpRequest = GAMRequest()
let ubKVP = [
"smaub": bidKeyword // make sure you add "smaub" as a Dynamic Key under Inventory >> Key-Values inside of GAM (no value as you will pass that here)
]
kvpRequest.customTargeting = ubKVP
let adLoader = GADAdLoader(adUnitID:"YOUR_GAM_AD_UNIT_ID",
rootViewController: {Your_Root_View_Controller},
adTypes: [ .native ],
options: [ ... ad loader options objects ... ])
adLoader.delegate = self
adLoader.load(kvpRequest)
}
}
[SmaatoSDK prebidNativeForAdSpaceId:@"SMAATO_ADSPACE_ID" completion:^(SMAUbBid * _Nullable bid, NSError * _Nullable error) {
if (bid) {
// Let's assume this is the max price of your line items (you will want to change this float to yours)
CGFloat maxPrice = 0.1;
NSString *bidKeyword;
// Helper to format bidKeyword if the received bid price is greater than max price. In this case, just add smaato_cpm prefix to the maxPrice (formatted value to the required fraction digits).
if (bid.bidPrice > maxPrice) {
bidKeyword = [NSString stringWithFormat:@"smaato_cpm:%.2f", maxPrice];
} else {
bidKeyword = bid.targetPrebidKeyword;
}
GAMRequest *kvpRequest = [[GAMRequest alloc] init];
NSDictionary<NSString *, NSString *> *ubKVP = [[NSDictionary alloc] initWithObjectsAndKeys:@"smaub", bidKeyword, nil]; // make sure you add "smaub" as a Dynamic Key under Inventory >> Key-Values inside of GAM (no value as you will pass that here)
kvpRequest.customTargeting = ubKVP;
GADAdLoader* adLoader = [[GADAdLoader alloc] initWithAdUnitID:@"YOUR_GAM_AD_UNIT_ID" rootViewController:{Your_Root_View_Controller} adTypes:[NSArray arrayWithObject:GADAdLoaderAdTypeNative] options:[ ... ad loader options objects ... ]];
adLoader.delegate = self;
[adLoader loadRequest:kvpRequest];
}
}];
Generic
SmaatoSDK.prebidNative(forAdSpaceId: "SMAATO_ADSPACE_ID") {[weak self] ubBid, error in
guard let bid = ubBid ,
let bidId = bid.metaData["smaato_ubid"] as? String,
let nativeAdRequest = SMANativeAdRequest(adSpaceId: "SMAATO_ADSPACE_ID") else {
return
}
let nativeAd = SMANativeAd()
nativeAd.delegate = self
let comps = bidId.components(separatedBy: ":")
if comps.count > 1 {
let params = SMAAdRequestParams()
params.ubUniqueId = comps.last
nativeAd.load(with: nativeAdRequest, requestParams: params)
} else {
nativeAd.load(with: nativeAdRequest)
}
}
[SmaatoSDK prebidNativeForAdSpaceId:@"SMAATO_ADSPACE_ID" completion:^(SMAUbBid _ _Nullable bid, NSError _ \_Nullable error) {
if (bid && bid.metaData[@"smaato_ubid"]) {
NSString *ubId = bid.metaData[@"smaato_ubid"];
SMANativeAd *nativeAd = [[SMANativeAd alloc] init];
nativeAd.delegate = self;
SMANativeAdRequest *adRequest = [[SMANativeAdRequest alloc] initWithAdSpaceId:@"SMAATO_ADSPACE_ID"];
NSArray<NSString *> *comps = [ubId componentsSeparatedByString:@":"];
if ([comps count] > 1) {
SMAAdRequestParams *requestParam = [[SMAAdRequestParams alloc] init];
requestParam.ubUniqueId = [comps lastObject];
[nativeAd loadWithAdRequest:adRequest requestParams:requestParam];
} else {
[nativeAd loadWithAdRequest:adRequest];
}
} else {
return;
}
}];
Outstream Ad request
To add Smaato Unified Bidding for Outstream Ads, follow these steps:
- First, find the line of code where you create a
GAMBannerViewinstance to add Smaato Unified Bidding prebid call. - Next, add the
UnifiedBidding.prebidOutstream(...)method call to your code in the as shown in the examples below. - The
bannerSizeparameter should match supported Smaato banner dimensions: standard size banner (320×50), medium rectangle size banner (300×250), leaderboard size banner (728×90), skyscraper banner size (120×600).
Then, move theloadAdmethod call to thePrebidListenercallback method and use Prebid data fromSMAUbBid*bid instance to build correct targeting string for Smaato Line Item (which you have created earlier via the GAM Dashboard). Finally, pass the UB bidKeyword string in Key-value form inside GAMRequest and call loadAd.
GAM Specific
Var outstreamView = GAMBannerView(adSize: kGADAdSizeBanner)
outstreamView.adUnitID = "YOUR_GAM_AD_UNIT_ID"
outstreamView.rootViewController = self
outstreamView.delegate = self
SmaatoSDK.prebidOutstream(forAdSpaceId: "SMAATO_ADSPACE_ID", bannerSize: .mediumRectangle_300x250) {(bid: SMAUbBid?, error: Error?) in
if let smaatoBid = bid {
// Let's assume this is the max price of your line items (you will want to change this float to yours)
let maxPrice : CGFloat = 0.1
let bidKeyword : String
// Helper to format bidKeyword if the received bid price is greater than max price. In this case, just add smaato_cpm prefix to the maxPrice (formatted value to the required fraction digits).
if smaatoBid.bidPrice > maxPrice {
bidKeyword = String(format: "smaato_cpm:%.2f", maxPrice)
} else {
bidKeyword = smaatoBid.targetPrebidKeyword
}
let kvpRequest = GAMRequest()
let ubKVP = [
"smaub": bidKeyword // make sure you add "smaub" as a Dynamic Key under Inventory >> Key-Values inside of GAM (no value as you will pass that here)
]
kvpRequest.customTargeting = ubKVP
outstreamView.load(kvpRequest)
}
}
GAMBannerView _outstreamView = \[[GAMBannerView alloc] initWithAdSize:GADAdSizeBanner];
outstreamView.adUnitID = @"YOUR_GAM_AD_UNIT_ID";
outstreamView.rootViewController = self;
outstreamView.delegate = self;
\[SmaatoSDK prebidOutstreamForAdSpaceId:@"SMAATO_ADSPACE_ID" bannerSize:kSMAUbBannerSizeXXLarge_320x50 completion:^(SMAUbBid _ \_Nullable bid, NSError \* \_Nullable error) {
if (bid) {
// Let's assume this is the max price of your line items (you will want to change this float to yours)
CGFloat maxPrice = 0.1;
NSString *bidKeyword;
// Helper to format bidKeyword if the received bid price is greater than max price. In this case, just add smaato_cpm prefix to the maxPrice (formatted value to the required fraction digits).
if (bid.bidPrice > maxPrice) {
bidKeyword = [NSString stringWithFormat:@"smaato_cpm:%.2f", maxPrice];
} else {
bidKeyword = bid.targetPrebidKeyword;
}
GAMRequest *kvpRequest = [[GAMRequest alloc] init];
NSDictionary<NSString *, NSString *> *ubKVP = [[NSDictionary alloc] initWithObjectsAndKeys:@"smaub", bidKeyword, nil]; // make sure you add "smaub" as a Dynamic Key under Inventory >> Key-Values inside of GAM (no value as you will pass that here)
kvpRequest.customTargeting = ubKVP;
[outstreamView loadRequest:kvpRequest];
}
}];
Generic
var outstreamView = SMAOutstreamView()
SmaatoSDK.prebidOutstream(forAdSpaceId: "SMAATO_ADSPACE_ID",bannerSize: .mediumRectangle_300x250) { [weak self] ubBid, error in
guard let bid = ubBid ,
let bidId = bid.metaData["smaato_ubid"] as? String else {
print("Bid has to be not nil")
return
}
let params = SMAAdRequestParams()
params.ubUniqueId = bidId
outstreamView.delegate = self
outstreamView.load(withAdSpaceId: "SMAATO_ADSPACE_ID",
outstreamAdSize: .medium_300x600,
requestParams: params)
}
SMAOutstreamView *outstreamView = [[SMAOutstreamView alloc]init];
[SmaatoSDK prebidOutstreamForAdSpaceId:@"SMAATO_ADSPACE_ID"
bannerSize:kSMAUbBannerSizeXXLarge_320x50
completion:^(SMAUbBid *_Nullable bid, NSError *_Nullable error) {
if (bid && bid.metaData[@"smaato_ubid"]) {
NSString *ubId = bid.metaData[@"smaato_ubid"];
SMAAdRequestParams *requestParam = [[SMAAdRequestParams alloc] init];
requestParam.ubUniqueId = ubId;
outstreamView.delegate = self;
[outstreamView loadWithAdSpaceId:@"SMAATO_ADSPACE_ID" adSize:kSMABannerAdSizeMediumRectangle_300x250 requestParams:requestParam];
} else {
return;
}
}];
Key-value targeting
Introducing age, gender and key-value targeting with the following setup:
Age and gender values are collected from Smaato SDK (UserInfo) interface that is already provided by the SDK.
Regarding Key-Value pairs, once the value is set for banners or interstitials, that value is collected for Unified Bidding to the corresponding request as well. Meaning, if the keyValuePairs were set in the SDK for Banners, that value is added to the banner prebid request. So, it does not have to be set again for Unified Bidding. The same approach would be applied to the other types.
- set user age and/or gender to Smaato SDK
- initialise a
SMAKeyValuePairsobject and set your targeting parameters by using the public interface - set the key-value pairs object to the proper property, to match the prebid request ad type.
- call
prebidmethod
Example code for Banners
// Setting age and gender
SmaatoSDK.userGender = kSMAGenderFemale;
SmaatoSDK.userAge = @30;
// Let's create and set targeting parameters
SMAKeyValuePairs *KVP = [SMAKeyValuePairs new];
[KVP setTargetingValue:@"30" forKey:@"Age"]; // replace with your key-value pairs configured on SPX site
[KVP setTargetingValues:@[@"Demo", @"Stage"] forKey:@"Application"]; // replace with your key-value pairs configured on SPX site
// Setting KV pairs for Banner request
SMABannerView.keyValuePairs = KVP;
// Prebid request
[SmaatoSDK prebidBannerForAdSpaceId:@<SMAATO_ADSPACE_ID>"
bannerSize:kSMAUbBannerSizeXXLarge_320x50
completion:^(SMAUbBid *_Nullable bid, NSError *_Nullable error) {
//Loading AdMob ad
}];
// Setting age and gender
SmaatoSDK.userAge = 35
SmaatoSDK.userGender = .male
// Defining Key-value targeting
let KVP = SMAKeyValuePairs()
KVP.setTargetingValues(["Demo", "Stage"], forKey: "Application") // replace with your key-value pairs configured on SPX site
KVP.setTargetingValues(["iOS", "Android"], forKey: "OS") // replace with your key-value pairs configured on SPX site
// Setting KV pairs for Banner request
SMABannerView.keyValuePairs = KVP
// Prebid request
SmaatoSDK.prebidBanner(forAdSpaceId: "adSpaceId",
bannerSize: .xxLarge_320x50) { (bidUnit, error) in
//Loading AdMob ad
}
The same approach works for Interstitial videos, but setting KVP dictionary to keyValuePairs property from SMAInterstitial.
// Setting KV pairs for Interstitial request
SMAInterstitial.keyValuePairs = KVP;
Important Details About GDPR
As a publisher, you should integrate a Consent Management Platform (CMP) and request for vendor and purpose consents as outlined in IAB Europe’s Mobile In-App CMP API v1.0: Transparency & Consent Framework. You can find a reference implementation of a web-based CMP and the corresponding native wrappers here in the IAB’s GDPR-Transparency-and-Consent-Framework.
If you are embedding your own custom CMP, the collected end-user consent information needs to be stored in NSUserDefaults using the following keys:
| Key | Type | Description |
|---|---|---|
| IABConsent_CMPPresent | Bool | Set to “YES” if a CMP that follows the IAB specification is present in the application. |
| IABConsent_SubjectToGDPR | NSString | “1” = Subject to GDPR “0” = Not subject to GDPR “-1” = Undetermined (default before initialization) |
| IABConsent_ConsentString | NSString | Base64-encoded consent string as defined in Consent string and vendor list format v1.1 |
| IABConsent_ParsedPurposeConsents | NSString | String of “0”s and “1”s, where the character at position N indicates the consent status to purposeID N as defined in the Global Vendor List |
| IABConsent_ParsedVendorConsents | NSString | String of “0”s and “1”s, where the character at position N indicates the consent status to vendorID N as defined in the Global Vendor List |
Important Note:
If the key
IABConsent_SubjectToGDPRis set to “1”, then you as a publisher need to make sure the keyIABConsent_ConsentStringcontains a valid consent string (user was asked to provide consent before serving the ad). Otherwise, such ad requests will be dropped on the server-side without a return.
// User is not subject to GDPR
[[NSUserDefaults standardUserDefaults] setObject:@"0" forKey:@"IABConsent_SubjectToGDPR"];
Important Details About CCPA
The California Consumer Privacy Act (CCPA) was created to provide California consumers with greater transparency and control over their personal information. In many ways, the CCPA is a first of its kind regulation in the United States that seeks to create broad privacy and data protection rules that apply to all industries doing business in the jurisdiction of California, rather than focusing on a single sector or specific data collection and use practices.
For more information about the CCPA regulation, please check out the Smaato FAQ.
For Publishers with California- Based Users
As a publisher, you need to make sure to request consent from California-based users (to give or refuse consent / to opt-out or opt-in ) about private data transfer. This answer should be saved in NSUserDefaults with key “IABUSPrivacy_String” in the US Privacy String format (CCPA Opt-Out Storage Format).
Sample of US Privacy String Saving in NSUserDefaults
NSUserDefaults- (void)saveCCPAUsPrivacyString:(NSString \*)usString
{
if (usString.length > 0) {
[NSUserDefaults.standardUserDefaults setObject:usString
forKey:@"IABUSPrivacy_String"];
}
}
private func saveCCPA(usPrivacy string: String?) {
guard let usString = string else {
return
}
UserDefaults.standard.set(usString, forKey: "IABUSPrivacy_String")
}
NextGen SDK reads that value by key “IABUSPrivacy_String” if it exists and uses it as an optional parameter for all ad requests. NextGen SDK allows to read this CCPA US Privacy String from NSUserDefaults to be sure NextGen SDK uses the same value, that you saved in NSUserDefaults and avoid any misalignment and misunderstanding. CCPA US Privacy String is available via SmaatoSDK.usPrivacyString public class property.
Updated about 1 month ago
