iOS SDK
Swift -- iOS 12+ -- v1.0.0
1. Installation
The Oprello Ads SDK is distributed as an OprelloAds.xcframework. Add it to your Xcode project as an embedded framework:
- Drag
OprelloAds.xcframeworkinto your Xcode project navigator. - Go to your target's General tab.
- Under Frameworks, Libraries, and Embedded Content, ensure
OprelloAds.xcframeworkis listed with Embed & Sign.
The framework supports both device (arm64) and simulator (x86_64 + arm64) architectures.
CocoaPods and Swift Package Manager distribution is planned. Contact partnerships@oprello.com to receive the XCFramework.
2. Initialization
Initialize the SDK as early as possible, typically in your AppDelegate or app entry point:
import OprelloAds
OprelloAdsManager.initialize(
appId: "YOUR_APP_ID",
onReady: {
// SDK is ready for ad requests
// You can start loading ads here
},
onConfigLoaded: {
// Server config loaded successfully
// Ad units are now validated
},
onFailure: { error in
// Initialization failed
print("Oprello init failed: \(error.localizedDescription)")
}
)The appId is found in the Oprello dashboard under your app settings.
3. Banner Ads
import OprelloAds
class ViewController: UIViewController, OprelloBannerAdDelegate {
var bannerAd: OprelloBannerAd!
override func viewDidLoad() {
super.viewDidLoad()
bannerAd = OprelloBannerAd(adUnitId: "YOUR_BANNER_AD_UNIT_ID")
bannerAd.delegate = self
// Load with a specific size
let size = BannerAdSize(width: 320, height: 50)
bannerAd.loadMetadata(size: size)
}
// MARK: - OprelloBannerAdDelegate
func bannerAdDidLoadMetadata(_ bannerAd: OprelloBannerAd, adResponse: BannerAdResponse) {
// Metadata loaded, now load assets
bannerAd.loadAssets()
}
func bannerAdDidLoadAssets(_ bannerAd: OprelloBannerAd) {
// Assets ready, show the ad in a container view
bannerAd.show(in: bannerContainerView)
}
func bannerAdDidTrackImpression(_ bannerAd: OprelloBannerAd) {
// Impression tracked
}
func bannerAdDidFailToLoadMetadata(_ bannerAd: OprelloBannerAd, error: Error) {
print("Banner load failed: \(error.localizedDescription)")
}
func bannerAdDidClick(_ bannerAd: OprelloBannerAd) {
// User clicked the ad
}
}Available predefined sizes: .banner320x50, .banner300x250, .banner728x90. Adaptive sizes via BannerAdSize.portrait(width:), BannerAdSize.small(width:), BannerAdSize.multipleOptions(_:), etc.
4. Interstitial Ads
import OprelloAds
class ViewController: UIViewController, OprelloInterstitialAdDelegate {
var interstitialAd: OprelloInterstitialAd!
override func viewDidLoad() {
super.viewDidLoad()
interstitialAd = OprelloInterstitialAd(adUnitId: "YOUR_INTERSTITIAL_AD_UNIT_ID")
interstitialAd.delegate = self
interstitialAd.loadMetadata()
}
// MARK: - OprelloInterstitialAdDelegate
func interstitialAdDidLoadMetadata(_ interstitialAd: OprelloInterstitialAd,
adResponse: InterstitialAdResponse) {
interstitialAd.loadAssets()
}
func interstitialAdDidLoadAssets(_ interstitialAd: OprelloInterstitialAd) {
// Ad is ready to present
}
func interstitialAdDidPresent(_ interstitialAd: OprelloInterstitialAd) {
// Full-screen ad presented
}
func interstitialAdDidDismiss(_ interstitialAd: OprelloInterstitialAd) {
// User closed the ad
}
func interstitialAdDidFailToLoadMetadata(_ interstitialAd: OprelloInterstitialAd, error: Error) {
print("Interstitial load failed: \(error.localizedDescription)")
}
// Present when ready (e.g., at a natural transition point)
func showInterstitial() {
if interstitialAd.isReady() {
interstitialAd.present(from: self)
}
}
}5. Rewarded Ads
import OprelloAds
class ViewController: UIViewController, OprelloRewardedAdDelegate {
var rewardedAd: OprelloRewardedAd!
override func viewDidLoad() {
super.viewDidLoad()
rewardedAd = OprelloRewardedAd(adUnitId: "YOUR_REWARDED_AD_UNIT_ID")
rewardedAd.delegate = self
rewardedAd.loadMetadata()
}
// MARK: - OprelloRewardedAdDelegate
func rewardedAdDidLoadMetadata(_ rewardedAd: OprelloRewardedAd,
adResponse: RewardedAdResponse) {
rewardedAd.loadAssets()
}
func rewardedAdDidLoadAssets(_ rewardedAd: OprelloRewardedAd) {
// Ad is ready to present
}
func rewardedAdDidEarnReward(_ rewardedAd: OprelloRewardedAd) {
// Grant the user their reward
}
func rewardedAdDidDismiss(_ rewardedAd: OprelloRewardedAd) {
// Check if reward was earned
if rewardedAd.hasEarnedReward() {
// Reward confirmed
}
rewardedAd.reset() // Reset for next ad load
}
func rewardedAdDidFailToLoadMetadata(_ rewardedAd: OprelloRewardedAd, error: Error) {
print("Rewarded load failed: \(error.localizedDescription)")
}
func showRewarded() {
if rewardedAd.isReady() {
rewardedAd.present(from: self)
}
}
}6. Native Ads
import OprelloAds
class ViewController: UIViewController, OprelloNativeAdDelegate {
var nativeAd: OprelloNativeAd!
override func viewDidLoad() {
super.viewDidLoad()
nativeAd = OprelloNativeAd(adUnitId: "YOUR_NATIVE_AD_UNIT_ID")
nativeAd.delegate = self
nativeAd.loadMetadata()
}
// MARK: - OprelloNativeAdDelegate
func nativeAdDidLoadMetadata(_ nativeAd: OprelloNativeAd, adResponse: NativeAdResponse) {
nativeAd.loadAssets()
}
func nativeAdDidLoadAssets(_ nativeAd: OprelloNativeAd) {
// Bind ad data to your custom views
let assets = nativeAd.assets
titleLabel.text = assets.primaryTitle
ctaButton.setTitle(assets.primaryCTA, for: .normal)
// Load images
if let mainImage = assets.mainImage,
let url = mainImage.url,
let image = nativeAd.getLoadedImage(for: url) {
mainImageView.image = image
}
// Register the container view for impression tracking
nativeAd.registerView(containerView)
}
func nativeAdDidClick(_ nativeAd: OprelloNativeAd) {
// User clicked the ad
}
// Handle clicks on CTA button
@IBAction func ctaTapped(_ sender: Any) {
nativeAd.handleClick()
}
}7. App Open Ads
import OprelloAds
class AppDelegate: UIResponder, UIApplicationDelegate, OprelloAppOpenAdDelegate {
var appOpenAd: OprelloAppOpenAd!
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
appOpenAd = OprelloAppOpenAd(adUnitId: "YOUR_APP_OPEN_AD_UNIT_ID")
appOpenAd.delegate = self
appOpenAd.loadMetadata()
return true
}
// MARK: - OprelloAppOpenAdDelegate
func appOpenAdDidLoadMetadata(_ appOpenAd: OprelloAppOpenAd,
adResponse: AppOpenAdResponse) {
appOpenAd.loadAssets()
}
func appOpenAdDidLoadAssets(_ appOpenAd: OprelloAppOpenAd) {
// Ad is ready to present on next app foreground
}
func appOpenAdDidDismiss(_ appOpenAd: OprelloAppOpenAd) {
// User closed the ad, load next one
appOpenAd.reset()
appOpenAd.loadMetadata()
}
// Present when app comes to foreground (in your scene delegate or lifecycle observer)
func sceneDidBecomeActive(_ scene: UIScene) {
if let rootVC = window?.rootViewController, appOpenAd.isReady() {
appOpenAd.present(from: rootVC)
}
}
}8. Privacy & Consent
Set privacy signals before loading ads. The SDK also auto-reads from IAB CMP UserDefaults keys.
// GDPR - set consent status and TCF string
OprelloAdsManager.setGDPRConsent(applies: true, consentString: "TCF_CONSENT_STRING")
// CCPA - set US Privacy string
OprelloAdsManager.setUSPrivacy("1YNN")
// GPP - set Global Privacy Platform string
OprelloAdsManager.setGPPConsent(gppString: "GPP_STRING", sectionIds: [2, 6])
// COPPA - for child-directed apps
OprelloAdsManager.setCOPPA(applies: true)
// Under age of consent
OprelloAdsManager.setUserIsUnderAgeOfConsent(true)9. App Tracking Transparency
On iOS 14+, request ATT authorization before initializing the SDK to allow the IDFA to be included in ad requests:
import AppTrackingTransparency
// Request ATT permission (typically in your first view controller)
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { status in
// Initialize Oprello after ATT response
OprelloAdsManager.initialize(
appId: "YOUR_APP_ID",
onReady: { /* ... */ },
onConfigLoaded: { /* ... */ },
onFailure: { error in /* ... */ }
)
}
}Add the NSUserTrackingUsageDescription key to your Info.plist with a description of why your app needs tracking permission.
10. SDK Size
The Oprello Ads SDK is distributed as an OprelloAds.xcframework containing arm64 (device) and x86_64 + arm64 (simulator) slices.
| Component | Approx. Size | Notes |
|---|---|---|
| OprelloAds.xcframework | ~1-2 MB | Full framework with all architectures |
| Device slice (arm64) | ~500 KB - 1 MB | Included in App Store builds |
The iOS SDK has no external dependencies -- it uses only system frameworks (UIKit, WebKit, AVFoundation, CoreTelephony, Network, AdSupport, AppTrackingTransparency, StoreKit). The actual IPA size increase is typically under 1 MB after App Store thinning removes unused architecture slices. Actual impact depends on your app's existing binary size and bitcode settings.
11. SKAdNetwork Setup
Oprello's SKAdNetwork registration is in progress. Contact partnerships@oprello.com for the latest status and your SKAdNetwork ID.
Once registered, you will add the Oprello SKAdNetwork identifier and any DSP partner identifiers to your Info.plist to enable attribution. We will provide the exact identifier to include.
The SDK handles SKAdNetwork impression tracking and conversion value updates automatically using SKAdNetwork APIs on iOS 14.0+. AdAttributionKit support is in development. Currently, SKAdNetwork is used for attribution.
You can manually update postback conversion values for attribution:
// Update conversion value after a meaningful in-app event
OprelloAdsManager.updatePostbackConversionValue(42)
// With coarse value for SKAdNetwork 4.0+ (iOS 16.1-17.3)
OprelloAdsManager.updatePostbackConversionValue(42, coarseValue: "high")12. Testing
Enable test mode to receive test creatives instead of production ads:
import OprelloAds
// Enable test mode
OprelloAdsTestManager.setTestMode(enabled: true)
// Check test mode status
let isTestMode = OprelloAdsTestManager.isTestModeEnabled
// Disable test mode for production
OprelloAdsTestManager.setTestMode(enabled: false)For debug logging, the SDK prints to the console with the tag OprelloAdsDebugLog. Filter your Xcode console output with this tag to see SDK activity. Debug logging is enabled by default and can be controlled via server config.