Skip to content
Open Portal

iOS SDK

Integrate Appylar in your iOS app.

Applies to Appylar v1.0

The Appylar iOS SDK (v1.0.0) is the Swift equivalent of the Android SDK: request and display ads, and promote your app across the network through campaigns. It's a pure-Swift package with no third-party dependencies. This page covers the complete public API.

You need an app key (app_live_…) from the portal before you start. See Getting Started.

#Requirements

Min iOS15.0
LanguageSwift 6, Xcode 16+
DistributionSwift Package Manager

No Info.plist changes are required — the SDK does not use App Tracking Transparency or SKAdNetwork in v1.

#Installation

#Swift Package Manager

Add the package in Xcode (File → Add Package Dependencies) or in Package.swift:

dependencies: [
    .package(url: "https://github.com/appylar/appylar-ios-sdk.git", from: "1.0.0"),
],
targets: [
    .target(
        name: "YourApp",
        dependencies: [.product(name: "Appylar", package: "appylar-ios-sdk")]
    ),
]

#CocoaPods

A CocoaPods podspec ships in the repo, but the pod isn't published to the CocoaPods trunk yet. Use Swift Package Manager for now — the pod 'Appylar' install line will be documented here once it's live.

#initialize()

Call initialize once at app startup. It's non-blocking and idempotent.

import Appylar

Appylar.initialize(appKey: "app_live_xxx")

#Configuration

Appylar.initialize(
    appKey: "app_live_xxx",
    config: AppylarConfig(testMode: false, logLevel: .info)
)
  • testMode — sandbox with deterministic test ads. Default false.
  • logLevel.none, .error, .warn, .info (default) or .debug.
Appylar.setConsent(Consent(gdprConsent: true, childDirected: false))
  • gdprConsent — consent for personalized advertising.
  • childDirected — COPPA / families mode.

The SDK does not show a consent dialog — collect consent with your own CMP and pass the result to setConsent.

BannerView is a UIView subclass. Add it to your view hierarchy and it loads itself once when it moves to a window — there's no load() call and no auto-refresh. The creative scales aspect-fit inside the view, so control the size with your own frame or Auto Layout constraints.

import Appylar
import UIKit

final class HomeViewController: UIViewController, BannerDelegate {
    private var banner: BannerView?

    override func viewDidLoad() {
        super.viewDidLoad()
        let banner = Appylar.bannerView()
        banner.delegate = self
        banner.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(banner)
        NSLayoutConstraint.activate([
            banner.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            banner.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            banner.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
            banner.heightAnchor.constraint(equalToConstant: 50),
        ])
        self.banner = banner
    }

    func bannerViewDidLoad(_ bannerView: BannerView) { }
    func bannerView(_ bannerView: BannerView, didFailToLoad error: AdError) { }
}

Call banner.destroy() when you remove it; it won't reload afterward.

#Interstitial

import Appylar
import UIKit

final class GameViewController: UIViewController, InterstitialDelegate {
    private var interstitial: Interstitial?

    func preloadAd() {
        let interstitial = Appylar.createInterstitial()
        interstitial.delegate = self
        interstitial.load()
        self.interstitial = interstitial
    }

    func interstitialDidLoad(_ interstitial: Interstitial) {
        interstitial.show(from: self)
    }
    func interstitial(_ interstitial: Interstitial, didFailToLoad error: AdError) { }
    func interstitialDidShow(_ interstitial: Interstitial) { }
    func interstitialDidDismiss(_ interstitial: Interstitial) { }
}

show(from:) presents a loaded ad from the given view controller. It's a no-op if nothing is loaded or one is already showing; showing in an invalid state delivers .invalidState.

#Delegates

Both delegate protocols have default (no-op) implementations, so you implement only what you need. All UI types are @MainActor; delegates are held weakly and callbacks arrive on the main actor.

DelegateMethodWhen
BannerDelegatebannerViewDidLoad(_:)Banner loaded
bannerView(_:didFailToLoad:)Load failed
InterstitialDelegateinterstitialDidLoad(_:)Ad ready
interstitial(_:didFailToLoad:)Load failed
interstitialDidShow(_:)Ad presented
interstitialDidDismiss(_:)Ad closed

#Errors

Failures arrive through the didFailToLoad delegate methods. AdError has exactly four cases:

CaseMeaning
.noFillNo eligible ad right now — expected, not a bug
.networkErrorNetwork or server error
.notInitializedAppylar.initialize(appKey:) hasn't run, or the key is invalid
.invalidStatee.g. showing an interstitial before a successful load

#Lifecycle

  1. Appylar.initialize(appKey:) once at startup; setConsent as early as possible.
  2. Banner: create → set delegate → add to the view hierarchy (it self-loads) → destroy() on removal.
  3. Interstitial: createInterstitial() → set delegateload()show(from:) on interstitialDidLoad.

One ad at a time; no preloading of multiple ads and no auto-refresh in v1.

#Sample app

Space Dash is a complete SwiftUI reference app built on this SDK — initialize, consent, a banner and an interstitial, with real loading, loaded, no-fill and error states and correct lifecycle. It uses only the public API and mirrors the Android sample. Find it under Examples/SpaceDash in the iOS SDK repository.

#Best practices

  • Initialize at launch so a token is ready before the first request.
  • Keep a strong reference to interstitials until they're dismissed.
  • Treat .noFill as normal.
  • Use .debug logging during integration, .info in production.

#Distribution store

The SDK reports its OS on every ad request, and Appylar routes each ad's click-through to the matching store listing — the App Store on iOS. iOS ships through a single store, so you rarely need to set this, but the option exists for parity across the SDKs:

Appylar.initialize(
    appKey: "app_live_xxx",
    config: AppylarConfig(store: .appleAppStore)
)

AppylarStore covers .googlePlay, .appleAppStore, .amazonAppstore, .huaweiAppGallery and .samsungGalaxyStore. See the serving protocol for how routing works.