Settings, AppConfig & lifecycle
A ready-made settings hub, one place for configuration, and the two lifecycle "asks" — timed to a genuine high, never on launch.
AppConfig — one source of truth
Pass an AppConfig to LaunchGate. Settings sections auto-hide based on what you configure.
LaunchGate(config: .myApp,
provider: PreviewPurchaseProvider(),
appConfig: AppConfig(
supportURL: URL(string: "https://delicious.works/support"),
privacyURL: URL(string: "https://delicious.works/privacy"),
feedbackEmail: "hello@delicious.works"
)) {
ContentView()
}
The settings hub
DeliciousKitSettingsView is a data-driven settings screen — Account and Purchases sections auto-hide when auth or IAP aren't configured. Inject your app's own sections via the trailing closure:
DeliciousKitSettingsView {
Section("Preferences") {
Toggle("Dark mode", isOn: $darkMode)
}
}
Review prompts
ReviewPrompter requests a review at a genuine high — never on launch, never after an error. Record your meaningful events and let it choose the moment:
ReviewPrompter.shared.recordEvent() // after a real win
What's New
Show a post-update sheet by passing a WhatsNewConfig:
LaunchGate(config: .myApp,
provider: PreviewPurchaseProvider(),
whatsNew: WhatsNewConfig(version: "1.2", items: [
.init(icon: "star.fill", title: "New feature", description: "…")
])) {
ContentView()
}
Both follow the same rule as permission prompts: earn it, time it to a high, and never nag. The timing philosophy lives in the Delicious Onboarding skill.