iOS development
app launch detection
iPhone app tips
coding Swift
mobile app tutorials

How to detect first time app launch on an iPhone

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The usual way to detect first launch on iPhone is to store a flag in UserDefaults the first time the app runs. On later launches, you read the flag and skip the onboarding or setup path.

The straightforward UserDefaults approach

For most apps, first launch means "first launch since install." UserDefaults matches that meaning well because its contents are removed when the app is deleted.

swift
1import Foundation
2
3enum LaunchTracker {
4    private static let hasLaunchedKey = "hasLaunchedBefore"
5
6    static func isFirstLaunch() -> Bool {
7        let defaults = UserDefaults.standard
8
9        if defaults.object(forKey: hasLaunchedKey) == nil {
10            defaults.set(true, forKey: hasLaunchedKey)
11            return true
12        }
13
14        return false
15    }
16}
17
18print(LaunchTracker.isFirstLaunch())
19print(LaunchTracker.isFirstLaunch())

On the first call, the key does not exist yet, so the method stores the marker and returns true. On later launches, the marker is already there and the method returns false.

Where to run the check

In a UIKit app, run the check during app startup and decide whether to show onboarding, a permissions explanation, or a one-time migration path. In a SwiftUI app, the same logic can live in an app state object or a small launch service that is consulted when the root view is created.

The important part is to make the check early enough that you can choose the correct initial flow before presenting the main interface.

First launch is not the same as first launch after update

Teams often mix up three different concepts:

  • first launch after install
  • first launch after reinstall
  • first launch after updating to a new app version

UserDefaults handles the first case well. If you need the version-update case, store the last launched app version and compare it with the current one. If you need data to survive reinstall, UserDefaults is not the right persistence layer for that requirement.

Why this is usually enough

The flag is small, local, and fast to read. That makes it a good fit for one-time UI behavior such as:

  • displaying onboarding screens
  • preloading default settings
  • recording first-run analytics
  • asking for permissions only after an explanation screen

The check should remain narrow in scope. "First launch" is a state transition, not a place to pile unrelated startup logic.

During development, you can reset the behavior by deleting the app from the simulator or clearing the stored defaults for the app target. That is useful when testing onboarding repeatedly, but it also highlights why production code should keep the rule simple and deterministic. A first-launch check should be easy to reason about when state is reset and when it is not.

Common Pitfalls

  • Using bool(forKey:) alone when you need to distinguish between "missing key" and an actual stored value.
  • Treating first launch after install and first launch after update as the same event.
  • Storing too much initialization behavior behind one first-run flag and making startup logic hard to reason about.
  • Expecting the flag to survive app deletion and reinstall.
  • Performing the check too late, after the main UI is already on screen.

Summary

  • 'UserDefaults is the standard solution for first launch detection on iPhone.'
  • Store a marker the first time the app runs and check for it on later launches.
  • Use object(forKey:) == nil when you need to know whether the key exists yet.
  • Keep "first launch" separate from "first launch after update" because they are different events.
  • Run the check early enough to choose the correct startup flow.

Course illustration
Course illustration

All Rights Reserved.