ASAScope iOS SDK
Apple Search Ads ROAS tracking for your iOS app. Zero external dependencies, privacy-first, 2 lines of code to integrate.
2-Line Setup
Import & configure
No IDFA
No ATT prompt needed
SPM Ready
Swift Package Manager
Requirements
| Dependency | Minimum |
|---|---|
| iOS | 15.0+ |
| Swift | 5.9+ |
| Xcode | 15.0+ |
Installation
Swift Package Manager (Recommended)
Add the package dependency to your Package.swift or use Xcode's built-in package manager.
// Package.swift
dependencies: [
.package(
url: "https://github.com/keremdemirios/ASAScope.git",
branch: "main"
)
]Xcode GUI
- Open your project in Xcode
- File → Add Package Dependencies
- Paste the URL:
https://github.com/keremdemirios/ASAScope - Select dependency rule Branch and choose main
- Select your target and click Add Package
branch: "main"instead of an from: "0.0.1" rule.Quick Start — UIKit
Add a single line in your AppDelegate to start tracking attribution automatically.
import ASAScope
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
ASAScope.shared.configure(apiKey: "YOUR_API_KEY")
return true
}
}Quick Start — SwiftUI
import SwiftUI
import ASAScope
@main
struct MyApp: App {
init() {
ASAScope.shared.configure(apiKey: "YOUR_API_KEY")
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}Configuration Options
You can customize the SDK behavior by passing a ConfigurationOptions object.
let options = ConfigurationOptions(
baseURL: URL(string: "https://your-custom-api.com"), // Custom API URL (optional)
autoFetchAttribution: true, // Auto-fetch on launch
debugLogging: true // Enable verbose logs
)
ASAScope.shared.configure(apiKey: "YOUR_API_KEY", options: options)| Option | Type | Default | Description |
|---|---|---|---|
| baseURL | URL? | nil | Override API base URL for self-hosted or testing |
| autoFetchAttribution | Bool | true | Automatically fetch attribution on configure() |
| debugLogging | Bool | false | Enable detailed debug logs in console |
Runtime Properties
| Property | Type | Description |
|---|---|---|
| ASAScope.shared.isConfigured | Bool | Whether the SDK has been configured |
| ASAScope.shared.deviceId | String | Persistent unique device identifier |
User Identity
After a user signs in to your app, link their identity so purchases can be attributed to the correct ad keyword.
// Call after successful authentication
ASAScope.shared.identify(userId: "user-123")identify as early as possible after login.Manual Attribution
If you set autoFetchAttribution: false, you can manually trigger attribution at any time.
Task {
let result = await ASAScope.shared.fetchAttribution()
if let result = result {
print("Attributed: \(result.attributed)")
print("Campaign: \(result.campaignName ?? "N/A")")
print("Keyword: \(result.keywordText ?? "N/A")")
}
}Webhook Setup (App Store Server Notifications)
To track revenue, you need to configure Apple's App Store Server Notifications to send purchase events to your ASAScope API.
Step 1: Get your webhook URL
Your webhook URL is:
https://asascopeapi-production.up.railway.app/webhooks/appleStep 2: Configure in App Store Connect
- Go to App Store Connect
- Select your app → App Information
- Scroll to App Store Server Notifications
- Set Production Server URL to your webhook URL above
- Set Sandbox Server URL to the same URL (for testing)
- Select Version 2 Notifications
How It Works
App Launch
SDK fetches an attribution token from Apple AdServices framework
Token Sent
Token is sent to ASAScope API, which exchanges it with Apple for campaign/keyword data
Purchase Event
When a user makes an in-app purchase, Apple sends a webhook to your ASAScope API
Attribution Match
ASAScope matches the purchase to the keyword that drove the install
ROAS Dashboard
Revenue and spend data are combined to show true ROAS per keyword on the dashboard
Privacy
No IDFA Required
Uses Apple AdServices — no ATT prompt needed
No User Tracking
The SDK does not track users across apps
Minimal Data
Only attribution token, device UUID, and SDK version are collected
Privacy Manifest Ready
Compatible with Apple's privacy requirements
Troubleshooting
Attribution token cannot be fetched
AdServices error: Error Domain=AEErrorDomain Code=0- This is expected on the iOS Simulator — the SDK returns a mock token automatically
- On a real device, ensure you are running iOS 15.0+ and the app is signed properly
API returns 401 Unauthorized
- Verify your API key is correct (check Dashboard → Settings → API Keys)
- Make sure the API key has not been revoked
- Ensure you are sending the key in the
x-api-keyheader
Webhook not received
- Check that you selected Version 2 in App Store Connect
- Confirm the URL is exactly
https://asascopeapi-production.up.railway.app/webhooks/apple - Try a sandbox purchase first to verify the integration
Debug logging not showing
- Set
debugLogging: truein ConfigurationOptions - Check Console.app with the filter
com.asascope.sdk