Oprello Logo
Back to Docs

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:

  1. Drag OprelloAds.xcframework into your Xcode project navigator.
  2. Go to your target's General tab.
  3. Under Frameworks, Libraries, and Embedded Content, ensure OprelloAds.xcframework is 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.

ComponentApprox. SizeNotes
OprelloAds.xcframework~1-2 MBFull framework with all architectures
Device slice (arm64)~500 KB - 1 MBIncluded 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.