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-integrationAfter 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.
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.
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
| Status | Recommended UI |
|---|---|
| .live | Render the creative and track qualified events. |
| .available | Optionally show a booking prompt using priceUSD, bookingURL, and nextAvailablePeriods. |
| .empty | Render 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
.availableor.emptystates. - 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:
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
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