iOS
The FalconMetrics iOS SDK enables seamless tracking of user conversion events in iOS applications. This SDK helps developers integrate powerful analytics and attribution capabilities to measure campaign performance, track user engagement, and analyze purchasing behaviors.
Requirements
- iOS 13.0+
- Swift 5.5+
- Xcode 13.0+
Installation
CocoaPods
Add the following to your App's Podfile:
pod 'FalconMetrics', '1.1.1'
Swift Package Manager
Add the following to your App's Package.swift:
dependencies: [
.package(url: "https://github.com/falconmetrics/falconmetrics-ios-spm.git", from: "1.1.0")
]
Quick Start
Initialize the SDK
Initialize the FalconMetrics SDK as early as possible in your app's lifecycle:
import FalconMetrics
import UIKit
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize FalconMetrics and store the task reference
let initTask = Task {
await FalconMetricsSdk.shared.initialize(apiKey: "YOUR_API_KEY")
}
// Optionally wait for initialization to complete
// Task { await initTask.value }
return true
}
IP Address Collection Setting
You can control how the SDK handles IP addresses sent to FalconMetrics during initialization using the ipAddressCollection parameter. This helps you meet regional privacy requirements (e.g., GDPR/CCPA).
Options (default is .full):
.full— Send full IP address.anonymized— Send anonymized/obfuscated IP address.disabled— Do not send IP address
Example:
Task {
await FalconMetricsSdk.shared.initialize(
apiKey: "YOUR_API_KEY",
developerDiagnostics: false,
trackingOptions: TrackingOptions(ipAddressCollection: .anonymized) // .full, .anonymized, or .disabled
)
}
Track Events
The SDK supports tracking various events with a simple, flexible, and type-safe API using specialized builders for each event type:
// Track a signup event
Task {
await FalconMetricsSdk.shared.createCompleteRegistrationBuilder().track()
}
// Track an add to cart event
Task {
await FalconMetricsSdk.shared.createAddToCartBuilder()
.withItemIds(["product-123","product-456"])
.withQuantity(1)
.withProductPrice(1999)
.withCurrency("USD")
.withProductCategory("Electronics")
.withCartId("cart-456")
.track()
}
// Track a purchase event
Task {
await FalconMetricsSdk.shared.createPurchaseBuilder()
.withItemIds(["product-123","product-456"])
.withQuantity(1)
.withTransactionId("tx-789")
.withProductPrice(1999)
.withCurrency("USD")
.withProductCategory("Electronics")
.withCartId("cart-456")
.withPaymentMethod("credit_card")
.withTax(150)
.withShipping(499)
.withDiscount(200)
.track()
}
// Track a subscription event
Task {
await FalconMetricsSdk.shared.createSubscriptionBuilder()
.withCurrency("USD")
.withPredictedValueInCents(10000)
.track()
}
// Track a custom event
//
// You can add optionally revenue and a currency to the event to write revenue to the ad network.
Task {
await FalconMetricsSdk.shared.createCustomEventBuilder()
.withEventName("custom_event")
.withAttributes(["key1": "value1", "key2": 100])
.withCurrency("USD")
.withRevenueInCents(10000)
.track()
}
User Data (Optional)
You can attach optional user data to any event to improve attribution accuracy and downstream matching. Provide only fields you have collected with proper user consent.
Available fields on UserData:
emailphoneNumberfirstNamelastNamepostalCodecitystatedateOfBirth(e.g., "1990-05-23")country(ISO 3166-1 alpha-2, e.g., "US")
Example:
Task {
let user = UserData(
email: "[email protected]",
phoneNumber: "+1-555-867-5309",
firstName: "Jane",
lastName: "Doe",
postalCode: "94105",
city: "San Francisco",
state: "CA",
dateOfBirth: "1990-05-23",
country: "US"
)
await FalconMetricsSdk.shared.createPurchaseBuilder()
.withItemIds(["sku-001"])
.withQuantity(1)
.withProductPrice(4999)
.withCurrency("USD")
.track(userData: user) // Attach user data here
}
Notes:
- User data is optional; pass
nilor omituserDataif you do not wish to include it. - Ensure your privacy disclosures and consent mechanisms cover the fields you send.
IDFA and App Tracking Transparency
The SDK provides methods to handle IDFA (Identifier for Advertisers) and App Tracking Transparency compliance:
Prerequisites
Add NSUserTrackingUsageDescription to your Info.plist with a clear purpose string.
<key>NSUserTrackingUsageDescription</key>
<string>We use IDFA to track user behavior and improve our services.</string>
- Ensure your privacy manifest (PrivacyInfo.xcprivacy) accurately declares tracking if applicable.
- Only show the ATT prompt when status is
.notDeterminedand after context-setting UI. - Defensive behavior: If NSUserTrackingUsageDescription is missing or empty, the SDK will NOT present the ATT prompt to avoid the system crash and will return
.denied. An error will be logged to help you diagnose the issue.
Request IDFA Permission
Request permission to track users across apps and websites:
Task {
let current = FalconMetricsSdk.shared.getTrackingAuthorizationStatus()
if current == .notDetermined {
let status = await FalconMetricsSdk.shared.requestIDFAPermission()
print("Tracking authorization status: \(status)")
} else {
print("Tracking authorization status (no prompt): \(current)")
}
}
Troubleshooting
- Missing NSUserTrackingUsageDescription: The ATT dialog will not be shown and the call will return
.denied. Add the key to your app target's Info.plist with a meaningful string value.
Check Current Authorization Status
Get the current App Tracking Transparency authorization status:
let status = FalconMetricsSdk.shared.getTrackingAuthorizationStatus()
switch status {
case .authorized:
print("Tracking is authorized")
case .denied:
print("Tracking is denied")
case .notDetermined:
print("Tracking authorization not determined")
case .restricted:
print("Tracking is restricted")
@unknown default:
print("Unknown tracking status")
}
Get IDFA
Retrieve the IDFA if tracking is authorized:
if let idfa = FalconMetricsSdk.shared.getIDFA() {
print("IDFA: \(idfa)")
} else {
print("IDFA not available - tracking not authorized")
}
Tracking Control
The SDK provides methods to enable or disable tracking for privacy compliance:
Enable/Disable Tracking
Control whether the SDK tracks events:
// Disable tracking (for privacy compliance)
Task {
await FalconMetricsSdk.shared.setTracking(enabled: false)
}
// Re-enable tracking
Task {
await FalconMetricsSdk.shared.setTracking(enabled: true)
}
Check Tracking Status
Check if tracking is currently enabled:
Task {
let isEnabled = await FalconMetricsSdk.shared.isTrackingEnabled()
if isEnabled {
print("Tracking is enabled")
} else {
print("Tracking is disabled")
}
}
Important Notes:
- Tracking is enabled by default when the SDK is first initialized
- When tracking is disabled, all event tracking calls are ignored
- SKAdNetwork postback initialization is skipped when tracking is disabled
- The tracking preference is persisted across app launches
- This setting is independent of IDFA/ATT authorization status
Update IP Address Collection at Runtime
If you need to change how IP addresses are handled after initialization (for example, when a user updates their privacy consent), you can update the tracking options at runtime:
// Switch to anonymized IP collection at runtime
FalconMetricsSdk.shared.updateTrackingOptions(
trackinOptions: TrackingOptions(ipAddressCollection: .anonymized)
)
// Or disable sending IP address entirely
FalconMetricsSdk.shared.updateTrackingOptions(
trackinOptions: TrackingOptions(ipAddressCollection: .disabled)
)
Best Practices
-
Initialize Early: Initialize the SDK as early as possible in your app's lifecycle to ensure all events are captured.
-
Event Consistency: Send consistent event parameters across sessions to ensure accurate analytics.
-
Price Formatting: With the new API, you can use decimal values (e.g., 19.99) for prices and amounts. The SDK automatically converts these to cents internally.
-
Error Handling: The SDK handles errors internally and won't throw exceptions, but it's good practice to wrap tracking calls in a Task.
-
Unique Identifiers: Use consistent and unique identifiers for products, carts, and transactions.
-
Builder Pattern: Use the builder pattern to add optional parameters to events. Only the required parameters are needed in the initial method call.
-
Type Safety: Take advantage of the type-safe
TrackingEventprotocol when creating custom events to ensure compile-time validation. -
Event Type Enum: Always use the
EventTypeenum for event types rather than string literals to benefit from compiler checks and code completion. -
Type Erasure: Use
AnyTrackingEventwhen you need to store or pass events of different types through a common interface.
License
© 2025 FalconMetrics LLC. All rights reserved.
This SDK is licensed under the FalconMetrics SDK License Addendum and is subject to the FalconMetrics Terms of Use, available at: https://www.falconmetrics.io/terms