Skip to main content

Prerequisites

System Requirements
  • Minimum iOS: 13.0
  • Xcode: 16.0+
  • Swift: 5.5+

Installation

The Velocity Ads SDK is distributed via Swift Package Manager.
1

Open Package Dependencies

In Xcode, go to File → Add Package Dependencies…
2

Enter Repository URL

Enter the package URL:
https://github.com/velocityiodev/velocityads-ios-sdk
3

Choose Version

Choose the version rule (e.g. “Up to Next Major” starting from 0.1.1) and add the package.
4

Add to Target

Add the VelocityAdsSDK library to your app target.
The package uses a binary target hosted on GitHub Releases. Each release (e.g. 0.1.1) provides a pre-built XCFramework; Xcode resolves the correct asset automatically when you select a version.

SDK Initialization

Initialize the SDK at app startup (e.g. in your AppDelegate or @main App struct):
import UIKit
import VelocityAdsSDK

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        VelocityAds.initSDK(appKey: "YOUR_APPLICATION_KEY")

        return true
    }
}
Important:
  • ⚠️ Initialize once during app startup
  • ⚠️ Must be called before loading any ads

Advanced Initialization with Callback

For better control and error handling:
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        VelocityAds.initSDK(
            appKey: "YOUR_APPLICATION_KEY",
            publisherUserId: "USER_12345",  // Optional: User identifier
            debug = false,  // Set to true to enable debug logging for troubleshooting
            callback: MyInitCallback()
        )

        return true
    }
}

class MyInitCallback: InitCallback {
    func onInitSuccess(sessionId: String, mediationEnabled: Bool) {
        print("SDK initialized successfully")
    }

    func onInitFailure(error: String) {
        print("Initialization failed: \(error)")
        // Handle initialization failure
    }
}

Loading Native Ads

The SDK provides a method for loading native ads: loadNativeAd(prompt:aiResponse:conversationHistory:dimensions:adUnitId:callback:) - Returns ad data model via callback (NativeAd)
VelocityAds.loadNativeAd(
    prompt: "What's the weather today?",
    aiResponse: "The weather is sunny with 72°F...",  // Optional: provide AI response for better targeting
    conversationHistory: nil,  // Optional: conversation history for better targeting
    dimensions: AdDimensions(width: 320, height: 50),  // Always provide ad dimensions in points
    adUnitId: "ad_unit_123",  // Optional
    callback: self
)

// AdCallback implementation
func onSuccess(nativeAd: NativeAd) {
    // Display ad manually
    titleLabel.text = nativeAd.title
    descriptionLabel.text = nativeAd.description
    ctaButton.setTitle(nativeAd.callToAction, for: .normal)

    // Load image (e.g. with URLSession or a library like SDWebImage)
    loadImage(from: nativeAd.imageUrl, into: adImageView)

    // Handle click
    ctaButton.addAction(UIAction { [weak self] _ in
        if let url = URL(string: nativeAd.clickUrl) {
            UIApplication.shared.open(url)
        }
    }, for: .touchUpInside)

    // Track impression
    trackImpression(nativeAd.impressionUrl)
}

func onError(error: String) {
    print("Failed to load ad: \(error)")
}

Ad Dimensions

Always provide ad dimensions in points (not pixels).
// Using view dimensions
let dimensions = AdDimensions(
    width: Int(adContainerView.bounds.width),
    height: Int(adContainerView.bounds.height)
)

// Using fixed dimensions
let dimensions = AdDimensions(
    width: 320,  // points
    height: 50   // points
)
Always specify dimensions in points, not pixels. iOS handles pixel density automatically.

Conversation History

For better ad targeting in chat applications, you can provide conversation history. The conversationHistory parameter accepts an array of dictionaries ([[String: Any]]?). Each dictionary should have:
  • "role" ("user" or "assistant")
  • "content" (message text)
Pass nil on the first call, then include the accumulated history on subsequent calls:
// First call - no conversation history
VelocityAds.loadNativeAd(
    prompt: "What's the weather today?",
    aiResponse: "The weather is sunny...",
    conversationHistory: nil,
    dimensions: AdDimensions(width: 320, height: 50),
    callback: adCallback
)

// Subsequent calls - with conversation history
let conversationHistory: [[String: Any]] = [
    ["role": "user", "content": "What's the weather today?"],
    ["role": "assistant", "content": "The weather is sunny..."]
]

VelocityAds.loadNativeAd(
    prompt: "What about tomorrow?",
    aiResponse: "Tomorrow will be cloudy...",
    conversationHistory: conversationHistory,
    dimensions: AdDimensions(width: 320, height: 50),
    callback: adCallback
)
Update the conversation history with the full conversation for best targeting.

GDPR

If your app serves users in the European Economic Area (EEA), UK, or other regions where GDPR applies, you must obtain user consent before processing their personal data. Method: VelocityAds.setConsent(_:) Parameters:
  • consent (Bool) - true if the user gives consent for data processing, false if the user denies consent
// User gives consent (GDPR)
VelocityAds.setConsent(true)

// User denies consent
VelocityAds.setConsent(false)
Geography-Specific: Only call this API in regions where GDPR regulations apply.

CCPA

If your app serves users in regions where CCPA applies, you must provide a way for users to opt out of the sale of their personal information. Method: VelocityAds.setDoNotSell(_:) Parameters:
  • doNotSell (Bool) - true if the user opts out of the sale of personal information, false if the user allows data sharing
// User opts out of data sale (CCPA)
VelocityAds.setDoNotSell(true)

// User allows data sharing
VelocityAds.setDoNotSell(false)
Geography-Specific: Only call this API in regions where CCPA regulations apply.

Advertising Identifiers

On iOS, access to IDFA is controlled by App Tracking Transparency (ATT). Your app must request tracking authorization when appropriate; the SDK uses the advertising identifier only when the user has granted permission.
The SDK does not perform cross-app tracking; the host app controls ATT and the SDK uses identifiers for ad delivery and analytics within your app.
The Velocity Ads SDK uses IDFA (Identifier for Advertisers) and IDFV (Identifier for Vendor) when available to improve ad performance and relevance. These identifiers enable:
  • Better ad targeting - More relevant ads for your users
  • Improved analytics - Better campaign performance measurement
  • Higher revenue - Increased eCPM through better targeting

Ad Load Example

This example shows how to integrate the SDK in a chat application with conversation history for better ad targeting.
import UIKit
import VelocityAdsSDK

class ChatViewController: UIViewController, AdCallback {
    private var conversationHistory: [[String: Any]] = []

    private func onUserMessage(_ userMessage: String) {
        // Get AI response
        getAIResponse(userMessage) { [weak self] aiResponse in
            guard let self = self else { return }
            // Display AI response
            self.displayMessage(aiResponse)

            // Load contextual ad with conversation history
            self.loadContextualAd(prompt: userMessage, aiResponse: aiResponse)

            // Add to conversation history after successful ad load
            self.conversationHistory.append(["role": "user", "content": userMessage])
            self.conversationHistory.append(["role": "assistant", "content": aiResponse])
        }
    }

    private func loadContextualAd(prompt: String, aiResponse: String?) {
        let width = Int(view.bounds.width)
        let height = 50
        let dimensions = AdDimensions(width: width, height: height)

        // Pass conversation history (empty on first call)
        let historyToPass = conversationHistory.isEmpty ? nil : conversationHistory

        VelocityAds.loadNativeAd(
            prompt: prompt,
            aiResponse: aiResponse,  // Optional
            conversationHistory: historyToPass,  // Optional conversation history
            dimensions: dimensions,
            adUnitId: nil,  // Optional
            callback: self
        )
    }

    func onSuccess(nativeAd: NativeAd) {
        // Display ad manually using custom UI
        displayAdManually(nativeAd)
    }

    func onError(error: String) {
        // Continue without ad
        print("Ad load failed: \(error)")
    }
}
Key Points
  • Conversation history is passed on subsequent ad loads
  • History starts empty (nil) on first call
  • Add messages to history after successful ad load
  • Handle errors gracefully by continuing without ads