I’m building an iOS app where users must complete an onboarding flow before accessing the main home screen. During onboarding, the user enters things like nickname and country.
After finishing onboarding, I set a flag in UserDefaults:
UserDefaults.standard.set(true, forKey: "hasCompletedOnboarding")
print("hasCompletedOnboarding:", UserDefaults.standard.bool(forKey: "hasCompletedOnboarding"))
This correctly prints hasCompletedOnboarding: true.
In my SceneDelegate, I check the flag like this:
let hasCompletedOnboarding = UserDefaults.standard.bool(forKey: "hasCompletedOnboarding")
If hasCompletedOnboarding is false, I show the onboarding. If it’s true, I show the main interface.
The problem:
If I wait ~10 seconds, force-close the app, and reopen it, hasCompletedOnboarding is printing false in SceneDelegate, and the onboarding shows again — even though I confirmed it was saved as true before closing the app.
So UserDefaults appears to save correctly during onboarding, but returns false after restarting.
What could cause this? Am I missing something in how UserDefaults works with SceneDelegate or app lifecycle? Any ideas or tips are appreciated.