Skip to main content

AttributionResult

Contains information about how the user discovered and installed your app.
public struct AttributionResult: Sendable, Decodable, Equatable

Properties

id

public let id: String
A unique identifier for this attribution record.

status

public let status: AttributionStatus
The attribution status. See AttributionStatus below.

campaignId

public let campaignId: Int?
The Apple Search Ads campaign ID.
Only available when status is .attributed.

campaignName

public let campaignName: String?
The Apple Search Ads campaign name.

adGroupId

public let adGroupId: Int?
The ad group ID within the campaign.

adGroupName

public let adGroupName: String?
The ad group name.

keywordId

public let keywordId: Int?
The keyword ID that triggered the ad.

keyword

public let keyword: String?
The keyword text that the user searched for.

countryOrRegion

public let countryOrRegion: String?
The two-letter country or region code (ISO 3166-1 alpha-2). Examples: "US", "GB", "JP", "DE"

clickDate

public let clickDate: Date?
The date and time when the user clicked the ad.
Only available when the user has opted into tracking.

conversionType

public let conversionType: String?
The type of conversion.
ValueDescription
"Download"New install
"Redownload"Reinstall

supplyPlacement

public let supplyPlacement: String?
The ad placement where the user saw the ad.
ValueDescription
"top_of_search"Top position in App Store search results
"search_results"Other positions in search results

Usage Example

let attribution = try await SpendOwl.attribution()

switch attribution.status {
case .attributed:
    print("Campaign: \(attribution.campaignName ?? "unknown")")
    print("Ad Group: \(attribution.adGroupName ?? "unknown")")
    print("Keyword: \(attribution.keyword ?? "unknown")")
    print("Country: \(attribution.countryOrRegion ?? "unknown")")

    if let clickDate = attribution.clickDate {
        print("Clicked: \(clickDate)")
    }

case .organic:
    print("User found the app organically")

case .unknown:
    print("Attribution data not yet available")
}

AttributionStatus

The attribution status indicating how the user acquired the app.
public enum AttributionStatus: String, Sendable, Decodable

Cases

attributed

case attributed
The user installed the app after clicking an Apple Search Ads advertisement. When attributed, the AttributionResult contains campaign, ad group, and keyword data.

organic

case organic
The user found and installed the app organically (not through ads). Organic installs don’t have campaign or keyword data.

unknown

case unknown
The attribution status could not be determined. Possible reasons:
  • Attribution data is still being processed
  • The device doesn’t support attribution
  • An error occurred during attribution lookup

Usage Example

let attribution = try await SpendOwl.attribution()

switch attribution.status {
case .attributed:
    // Paid user - show premium onboarding
    showPremiumOnboarding()

case .organic:
    // Organic user - show standard onboarding
    showStandardOnboarding()

case .unknown:
    // Can't determine - use default
    showStandardOnboarding()
}

Status Comparison

StatusCampaign DataKeyword DataTypical Scenario
.attributedAvailableAvailableUser clicked an ad
.organicnilnilUser found app in App Store
.unknownnilnilAttribution pending or unavailable