Push notifications

Push sits behind a PushProvider, the same swap-point pattern as auth and purchases. DeliciousKit ships NoPushProvider (disabled), PreviewPushProvider (logs intent, for development), and — via DeliciousKitOneSignal — a real OneSignal-backed implementation.

Consent priming

Ask for push permission at the right moment, not at launch — PushController.requestAndRegister() is meant to be called from a moment in your onboarding or first-run flow where the value of notifications is already obvious, not from App.init(). The .permission onboarding step handles the three-state UI (ask / granted / denied → Open Settings) for you.

OneSignal

import DeliciousKitOneSignal. Push isn't a LaunchGate parameter — your app owns a PushController and drives it directly (most naturally from a .permission onboarding step):

@main
struct MyApp: App {
  // Construct once, early — OneSignalPushProvider.init calls OneSignal.initialize.
  let push = PushController(provider: OneSignalPushProvider(appID: "your-onesignal-app-id"))

  var body: some Scene {
    WindowGroup {
      LaunchGate(config: .myApp, provider: PreviewPurchaseProvider()) {
        ContentView().environmentObject(push)
      }
    }
  }
}
// From a .permission step's request closure, or a "turn on notifications" button:
await push.requestAndRegister()

push.identify(userID: user.id)   // after sign-in — links delivery to your user, not just the device
push.tag("goal", "fitness")      // segmentation for targeted campaigns
  • Construct OneSignalPushProvider(appID:) once, early (a let on your App struct), not lazily inside a view — its init calls OneSignal.initialize.
  • Your Xcode project needs the Push Notifications capability and a Notification Service Extension target for rich media — OneSignal's own setup docs cover the Xcode-side capability wiring; this page covers the DeliciousKit side only.

Preview & disabled providers

PreviewPushProvider()   // logs "would register for push" — no real SDK needed
NoPushProvider()        // fully disabled, for apps with integrations.push == none