RedChurn

SDK Swift (iOS)

SDK SwiftUI natif pour iOS 15+. Configurez une fois, affichez la récupération des paiements, les cancel saves et le win back, et modifiez tous les textes et offres depuis le tableau de bord RedChurn sans release App Store.

Installer avec l'IA

Cliquez sur un outil pour copier un prompt d'intégration prêt à coller, avec votre clé SDK et les extraits de code.

Télécharger le SDK v0.4.0
Ou ajoutez via SwiftPM : https://github.com/redchurn/swift-sdk

Vue d'ensemble

Le SDK Swift connecte votre app iOS à RedChurn via une seule clé API. Il enregistre votre App User ID RevenueCat, synchronise la configuration distante et affiche du SwiftUI natif pour trois scénarios de rétention.

Tout ce que voit l'abonné (titres, messages, boutons, offres) se modifie dans le tableau de bord. Le SDK interroge les changements et se met à jour automatiquement — vous ne publiez pas une nouvelle build pour modifier les textes.

  • Cancel Save : intercepte les appuis sur annuler avec une feuille native
  • Billing Recovery : relance in-app quand RevenueCat signale un problème de facturation
  • Win back : invite de réactivation pour les abonnés churnés
  • Config distante : flux, textes et offres pilotés depuis le tableau de bord

Prérequis

  • iOS 15 ou ultérieur (macOS 12+ aussi pris en charge)
  • Swift 5.9 / Xcode 15 ou ultérieur
  • SwiftUI (les contrôleurs sont ObservableObject)
  • RevenueCat configuré dans votre app avec des App User IDs
  • Capacité Push Notifications activée si vous utilisez le push serveur

1. Installation (Swift Package Manager)

Dans Xcode : Fichier → Ajouter des dépendances de package, puis collez l'URL du dépôt. Ou ajoutez-le aux dépendances de votre Package.swift.

swift
// Package.swift
dependencies: [
  .package(url: "https://github.com/redchurn/swift-sdk", from: "0.4.0"),
],
// then add "RedChurn" to your target's dependencies

2. Configuration au lancement

Appelez Redchurn.configure une fois dans le init() de votre @main App. Récupérez votre clé SDK dans le tableau de bord RedChurn (Paramètres, ou pendant l'onboarding). Passez l'App User ID RevenueCat pour que RedChurn puisse associer les abonnés aux événements webhook. Gardez notificationsEnabled pour planifier des rappels locaux à partir des textes du tableau de bord.

swift
import SwiftUI
import Redchurn
import RevenueCat

@main
struct MyApp: App {
  init() {
    Redchurn.configure(
      sdkKey: "rdchrn_live_xxxxxxxx",
      rcAppUserId: Purchases.shared.appUserID,
      notificationsEnabled: true
      // debug: true            // optional — prints SDK diagnostics
    )
  }

  var body: some Scene {
    WindowGroup { RootView() }
  }
}

3. Définissez l'App User ID après la connexion

Si l'App User ID RevenueCat n'est pas disponible au lancement, définissez-le après l'authentification pour cibler le bon abonné :

swift
// After your user logs in:
Redchurn.shared.setRCAppUserId(user.revenueCatAppUserId)

4. Cancel Save

Créez un RedchurnCancelFlowController et montez CancelSaveSheet sur votre écran de paramètres. interceptCancel() affiche la feuille de sauvegarde (sondage puis offres) et renvoie false quand rien ne doit s'afficher, pour retomber sur l'UI d'annulation du store. Appliquez l'offre acceptée dans onOfferAccepted via RevenueCat — lancez une exception en cas d'échec pour que RedChurn ne compte une sauvegarde qu'après une opération store/RC réussie.

swift
import SwiftUI
import Redchurn
import RevenueCat

struct SubscriptionSettings: View {
  @StateObject private var cancelFlow = RedchurnCancelFlowController(
    rcAppUserId: Purchases.shared.appUserID,
    onOfferAccepted: { offer in
      try await applyRetentionOffer(offer) // throw on failure — save only on success
    }
  )

  var body: some View {
    VStack {
      Button("Cancel subscription") {
        Task {
          let intercepted = await cancelFlow.interceptCancel()
          if !intercepted {
            try? await AppStore.showManageSubscriptions(in: scene)
          }
        }
      }
      CancelSaveSheet(controller: cancelFlow)
    }
  }
}

5. Billing Recovery

Quand RevenueCat signale un problème de facturation, RedChurn affiche une bannière de relance in-app à la prochaine ouverture et (avec notificationsEnabled) planifie des rappels locaux. Montez BillingRecoveryBanner près du haut de votre écran d'accueil et revérifiez à chaque appui sur notification.

swift
import SwiftUI
import Redchurn
import RevenueCat

struct HomeView: View {
  @StateObject private var billing = RedchurnBillingRecoveryController(
    rcAppUserId: Purchases.shared.appUserID
  )

  var body: some View {
    VStack {
      BillingRecoveryBanner(controller: billing)
      YourHomeContent()
    }
    .onReceive(NotificationCenter.default.publisher(for: .redchurnDidOpenFromNotification)) { note in
      guard let flow = note.object as? RedchurnFlow, flow == .billingRecovery else { return }
      Task { await billing.check() }
    }
  }
}

6. Win back

Pour les abonnés churnés (EXPIRATION RevenueCat), WinBackPrompt affiche votre offre de réactivation à la prochaine ouverture. Dirigez le CTA vers votre paywall.

swift
import SwiftUI
import Redchurn
import RevenueCat

struct HomeView: View {
  @StateObject private var winBack = RedchurnWinBackController(
    rcAppUserId: Purchases.shared.appUserID
  )

  var body: some View {
    YourHomeContent()
      .background(
        WinBackPrompt(controller: winBack, onCtaPress: { openPaywall() })
      )
      .onReceive(NotificationCenter.default.publisher(for: .redchurnDidOpenFromNotification)) { note in
        guard let flow = note.object as? RedchurnFlow, flow == .winBack else { return }
        Task { await winBack.check() }
      }
  }
}

7. Router les appuis sur notification

Pour qu'un appui sur une notification de récupération des paiements / win back ouvre le bon flux, transmettez la charge utile à RedchurnNotificationRouting depuis votre UNUserNotificationCenterDelegate. Il publie redchurnDidOpenFromNotification (géré par les contrôleurs ci-dessus) et ignore les notifications non liées.

swift
import UserNotifications
import Redchurn

func userNotificationCenter(
  _ center: UNUserNotificationCenter,
  didReceive response: UNNotificationResponse,
  withCompletionHandler completionHandler: @escaping () -> Void
) {
  if RedchurnNotificationRouting.handleNotificationResponse(
    userInfo: response.notification.request.content.userInfo
  ) != nil {
    completionHandler()
    return
  }
  // your other notification handling…
  completionHandler()
}

8. Push serveur (optionnel)

Les notifications locales ne partent que tant que l'app a tourné. Pour joindre les abonnés qui ne rouvrent jamais l'app, RedChurn envoie aussi du push serveur via APNs, déclenché par le webhook RevenueCat. Sur iOS, vous devez transmettre le token APNs natif — il ne s'enregistre pas automatiquement.

Demandez l'autorisation, enregistrez-vous pour les notifications distantes, puis transmettez le token dans votre AppDelegate. Ajoutez votre clé APNs .p8 (Key ID, Team ID, Bundle ID) une fois dans Tableau de bord → Intégrations → Notifications push.

  • Identifiants par app (BYOK) : clé APNs .p8 dans Tableau de bord → Intégrations
  • Sandbox vs Production : les builds Debug depuis Xcode utilisent le sandbox ; TestFlight et App Store utilisent la production
  • Testez de bout en bout depuis Tableau de bord → Événements → Tester les notifications push
swift
import UIKit
import UserNotifications
import Redchurn

// 1. Ask permission and register with APNs (e.g. after login)
UNUserNotificationCenter.current()
  .requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in
    guard granted else { return }
    DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() }
  }

// 2. Forward the APNs token to RedChurn
func application(
  _ application: UIApplication,
  didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
  Task { await Redchurn.shared.registerPushToken(deviceToken) }
}

Configuration distante

Une fois le SDK installé, tout le contenu visible par l'abonné se gère dans le tableau de bord. Activez ou désactivez les flux, modifiez les textes, changez les offres et mettez à jour le style. Les changements se propagent en moins de 60 secondes.

Le SDK interroge un endpoint /version léger et ne retélécharge la configuration que lorsque quelque chose a changé, plus un rafraîchissement quand l'app revient au premier plan. Observez Redchurn.shared.ready / remoteConfig en SwiftUI si vous devez réagir.

  • Flux et textes in-app : Tableau de bord → Scénarios → In-app
  • Offres d'annulation : Tableau de bord → Cancel saves
  • Séquences e-mail : Tableau de bord → Scénarios → E-mail
  • Branding et CTA de secours : Tableau de bord → Paramètres

Comment le SDK communique avec RedChurn

Tout le réseau passe par un acteur interne qui communique avec https://app.redchurn.io, authentifié avec votre clé SDK en Bearer token. Les requêtes ont un timeout de 12 secondes et seul /outcomes est réessayé, car c'est l'appel qui crédite le MRR sauvegardé.

rcAppUserId est la clé qui joint le SDK à vos événements webhook RevenueCat côté serveur, pour qu'un problème de facturation détecté par webhook affiche la bonne invite in-app au même abonné.

Auth headers · bash
Authorization: Bearer rdchrn_live_xxxxxxxx
Accept: application/json
X-RedChurn-Sdk-Version: 0.4.0
Accept-Language: fr            # when a locale is set
Endpoints used by the SDK · text
POST /api/sdk/v1/register     heartbeat + APNs token registration
GET  /api/sdk/v1/config       full remote config (flows, copy, offers)
GET  /api/sdk/v1/version      lightweight change check (polled)
GET  /api/sdk/v1/prompts      contextual billing-recovery / win-back prompts
POST /api/sdk/v1/events       APP_OPEN, CANCEL_SESSION, PROMPT_SHOWN/DISMISSED, LINK_OPENED
POST /api/sdk/v1/outcomes     saved / declined / dismissed (retried)

Comportement fail-safe

Le SDK ne lance jamais d'exception dans votre app. Avec une clé SDK invalide, il tourne en mode no-op et vos vues s'affichent normalement. interceptCancel() est fail-open : un abonné peut toujours accéder au store.

Utilisez le callback onError pour journaliser les problèmes non fatals vers votre outil de monitoring.

swift
Redchurn.configure(
  sdkKey: "rdchrn_live_xxxxxxxx",
  rcAppUserId: Purchases.shared.appUserID,
  onError: { error in
    // Sentry.capture(message: "[RedChurn] \(error)")
  }
)

Checklist production

  • Webhook RevenueCat connecté et livrant des événements
  • Clé SDK de l'environnement de production (rdchrn_live_...)
  • App User ID défini pour chaque abonné authentifié
  • Bouton d'annulation câblé via interceptCancel(), pas un lien direct vers le store
  • BillingRecoveryBanner et WinBackPrompt montés sur votre écran d'accueil
  • Appuis sur notification routés via RedchurnNotificationRouting
  • Clé APNs ajoutée dans Tableau de bord → Intégrations et token transmis (si push serveur)
  • Textes et offres in-app relus dans le tableau de bord avant le lancement

Installation depuis SwiftPM ou téléchargement

SwiftPM est le chemin recommandé. Vous pouvez aussi télécharger l'archive SDK via le bouton en haut de cette page et glisser le dossier dans votre projet, ou le mirroir dans un dépôt Git privé.

swift
.package(url: "https://github.com/redchurn/swift-sdk", from: "0.4.0")