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.
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
- '
UserDefaultsis 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:) == nilwhen 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.

