Respectlytics Respect lytics
Menu
Swift (iOS) Tutorial finish Privacy-first

How to track tutorial completion in Swift (iOS) without personal data

Tutorial completion is the cleanest activation signal in games and one of the highest-leverage in SaaS. Most analytics SDKs default to ingesting tutorial step metadata, time-spent-per-step, and abandonment-screen identifiers. Respectlytics helps developers avoid collecting personal data in the first place: in Swift (iOS), each tutorial step is its own named event, with no payload. Below: instrumenting the step funnel, computing first-time-user activation, and why per-step durations are a server-side derivation.

Fire one event per step completion — tutorial_step_1_complete, tutorial_step_2_complete, etc. — and a final tutorial_complete. Don't pass step numbers as parameters. The pattern matches onboarding-completion intentionally; the two events serve different products but the funnel discipline is identical.

Install the Swift (iOS) SDK

swift Respectlytics
// Package.swift
dependencies: [
    .package(url: "https://github.com/respectlytics/respectlytics-swift.git", from: "3.0.0")
]
// Or via Xcode → File → Add Packages → paste the URL above.

The SDK ships only via Swift Package Manager. CocoaPods and Carthage are not published — fewer integration paths means fewer surfaces to keep audited.

Initialize Respectlytics in Swift (iOS)

swift Respectlytics
import Respectlytics

@main
struct MyApp: App {
    init() {
        Respectlytics.configure(appKey: "<YOUR_APP_KEY>")
    }
    var body: some Scene { WindowGroup { ContentView() } }
}

Call configure once at app launch — typically in your App struct's init. No Info.plist keys are required: the SDK does not call ATTrackingManager and does not request the IDFA, so NSUserTrackingUsageDescription should NOT be added.

Track the event in Swift (iOS)

swift Respectlytics
import Respectlytics

func reportTutorialStep(_ step: Int) {
    Respectlytics.track("tutorial_step_\(step)_complete")
}

func reportTutorialFinish(skipped: Bool) {
    Respectlytics.track(skipped ? "tutorial_skipped" : "tutorial_complete")
}

If your tutorial branches (e.g. easy vs hard mode tutorial), distinct event names per branch: tutorial_complete_easy, tutorial_complete_hard.

Privacy & implementation notes

Common confusion: "tutorial" and "onboarding" are different events. Onboarding is account / profile setup (sign in, opt in, give consent, verify email); tutorial is feature instruction (how to play the game, how to navigate the app). Most apps have both, with different drop-off patterns. Instrument them as separate funnels.

First-day retention from tutorial completion is the most actionable single metric a games team can read — it tells you whether the introduction is doing its job. Session-grouped Respectlytics events give you the rate; per-player retention curves live in your game backend if you need them at the individual level.

Apple rejected approximately 3% of apps in 2024 for incorrectly omitting NSUserTrackingUsageDescription when ATT was required by the SDKs they shipped. Respectlytics doesn't trigger ATT. The corollary is also true: do not add the key on Respectlytics's account — its presence implies you track across apps, even if your code never calls requestTrackingAuthorization.

Internally the Swift SDK uses Swift Concurrency: events are queued in an actor-isolated buffer (RAM-only), flushed on a 30-second timer and on UIApplication.willResignActiveNotification. Force-quit before flush drops queued events — by design. There is no UserDefaults or file backing.

How this compares to other analytics SDKs

Tutorial finish eventFirebase AnalyticsMixpanelRespectlytics
Step number as parameterRecommendedRecommendedUse distinct event_name
Time-on-step in secondsRecommendedRecommendedServer-side derivation
Skip-tutorial as parameterRecommendedRecommendedUse distinct event_name
Per-user tutorial completion historyYesYesOut of scope
Step-by-step funnel ratePer-userPer-userSession-grouped

Frequently asked questions

Should we differentiate skipped vs completed?

Yes, distinct event names: tutorial_complete, tutorial_skipped. The ratio is product information — a high skip rate may mean the tutorial is redundant or annoying; a low skip rate may mean it's actually useful. Either interpretation needs the two signals separated.

What about tutorials with branches (gameplay style choice, e.g. easy vs hard)?

Distinct event names per branch: tutorial_complete_easy, tutorial_complete_hard. Per-branch retention curves come from comparing subsequent retention events across the two cohorts.

Do we measure D1 retention from tutorial finish?

Session-scoped, yes — the rate of sessions emitting any meaningful event in the 24-hour window after a session that emitted tutorial_complete is your D1-from-tutorial signal. Country / platform breakdowns surface the variation.

How is this different from `onboarding-completion`?

Onboarding is account-level setup (email verification, push opt-in, profile creation). Tutorial is gameplay/feature-level instruction. Most apps have both — a sign-in flow + a how-to-use-the-app flow. Treat them as distinct, and instrument both.

Related guides

Track what matters. Collect nothing you don't.

Five-field event schema, RAM-only event queue, no IDFA, no AAID, no persistent user IDs. Helps developers avoid collecting personal data in the first place.