Developer Docs / iOS SDK / Sponsorships

Native sponsor placements, built-in or completely custom

Fetch the current sponsor or availability state with a dashboard slot key. Use GrowthCat's SwiftUI banner or render the complete SDK-safe payload with your own design system.

1. Overview

Sponsorship rendering requires iOS 17 or later and the standard GrowthCat.initialize call. Configure a sponsor placement in the dashboard, then use its stable slotKey in the app.

The SDK response never contains private publisher or buyer data. It includes only the content needed to render the placement, its signed tracking data, public booking URL, price, and availability periods.

Use the GrowthCat iOS integration skill

The SDK repository includes a Codex skill that inspects the app's pinned Swift package revision, reads its matching documentation and public declarations, and integrates referrals, ads, sponsorships, feedback, or privacy configuration using the app's existing architecture.

Install the skill from
https://github.com/lapreamarcelo/GrowthCatSDK-ios/tree/main/skills/growthcat-integration

After installation, ask Codex for the feature and screen you want:

Use $growthcat-integration to add native feedback to my Settings screen.

2. Built-in sponsor banner

The built-in view fetches the slot, renders the current sponsor or booking placeholder, opens the destination, and tracks qualified impressions and clicks automatically.

Swift
import GrowthCat
import SwiftUI

struct HomeView: View {
    var body: some View {
        VStack {
            // Your content
            GrowthCatSponsorBannerView(slotKey: "home_sponsor")
        }
    }
}

3. Custom sponsor UI

Fetch one GrowthCatSponsorData value and keep that same value for as long as the creative remains on screen. It exposes the full slot content, creative, click and booking URLs, availability, and one stable creative instance ID.

Swift
struct CustomSponsorCard: View {
    @State private var data: GrowthCatSponsorData?

    var body: some View {
        Group {
            if let data, data.status == .live, let creative = data.creative {
                Button {
                    Task {
                        _ = await GrowthCat.shared.trackSponsorClick(data)
                        if let url = data.clickURL {
                            await UIApplication.shared.open(url)
                        }
                    }
                } label: {
                    VStack(alignment: .leading) {
                        Text("Sponsored")
                        Text(creative.headline ?? creative.sponsorName ?? "Sponsor")
                        if let body = creative.body { Text(body) }
                        if let cta = creative.ctaText { Text(cta) }
                    }
                }
                // Feed observations from your visibility measurement layer
                // to trackSponsorImpression. Do not infer visibility from load time.
            } else if let data, data.status == .available,
                      let url = data.bookingURL {
                Link("Sponsor this app", destination: url)
            }
        }
        .task {
            data = try? await GrowthCat.shared.loadSponsorData(
                slotKey: "home_sponsor"
            )
        }
    }
}

4. Sponsor response states

StatusRecommended UI
.liveRender the creative and track qualified events.
.availableOptionally show a booking prompt using priceUSD, bookingURL, and nextAvailablePeriods.
.emptyRender nothing because no sponsor is live and the placeholder is disabled.

5. Viewability and tracking

  • Show a clear Sponsored disclosure in every custom design.
  • Record an impression only after at least 50% visibility for one continuous second.
  • Do not track .available or .empty states.
  • Reuse the same render-data object for its impression and clicks to preserve creativeInstanceID.
  • Call the click helper only after a deliberate user interaction.

After your visibility observer confirms the threshold, pass the measured fraction and continuous duration to the helper:

Swift
let sponsor = try await GrowthCat.shared.loadSponsorData(
    slotKey: "home_sponsor"
)

_ = await GrowthCat.shared.trackSponsorImpression(
    sponsor,
    visibleFraction: 0.8,
    visibleDuration: 1.1
)

_ = await GrowthCat.shared.trackSponsorClick(sponsor)

6. API reference

Swift
func sponsor(slotKey: String) async throws -> SponsorSlotContent
func loadSponsorData(slotKey: String) async throws -> GrowthCatSponsorData

func trackSponsorImpression(
    _ data: GrowthCatSponsorData,
    visibleFraction: Double,
    visibleDuration: TimeInterval
) async -> Bool

func trackSponsorClick(
    _ data: GrowthCatSponsorData
) async -> Bool