Sahithi Ammana
Sahithi Ammana

Reputation: 81

User defaults are getting cleared on relaunching the app after long time

I have an iOS app where we can login and I'm using user defaults to store data like "firstLogin", "freshInstall", "userName", "sessionTime", etc. I am getting a problem where killing the app(double click on home and swipe up on the app to remove it) and relaunching it after a long time(after about 6hrs) is clearing all the userDefaults I'm setting and the app is opening in fresh install screen. It should actually open in logged in state.

I am using synchronize to properly save the userDefaults.

I don't have any code to explicitly delete the userDefault key-values or clear them. I have a few third party frameworks but I'm not sure how to check if those are causing this issue. How do I know where this problem is coming from? Is there any case where userDefaults gets cleared like that automatically?

The launch screen is determined based on the variable "isLaunchScreenShown" which is being saved in [NSUserDefaults standardUserDefaults]. After 1st install and launch screen is shown, the variable is set as true. When app is uninstalled, the UserDefaults are cleared. But in my case now, the UserDefaults' value for "isLaunchScreenShown" is returning null indicating that it is not set even though it is not the 1st launch after install.

Upvotes: 6

Views: 4547

Answers (2)

Beau Nouvelle
Beau Nouvelle

Reputation: 7252

This is related to the new prewarming feature Apple introduced with iOS 15.

https://developer.apple.com/documentation/uikit/app_and_environment/responding_to_the_launch_of_your_app/about_the_app_launch_sequence

It's not supposed to get as far as didFinishLaunching, but one commenter on the dev forums said that it does with their information coming from Apple directly.

Could be a bug. Could be intentional. There are some reports that this has been fixed in 15.4, however it's impossible to confirm because there's no way to know when a prewarm occurs.


Why UserDefaults and Keychain?

Generally prewarming can happen when the device is locked. If it's locked then access to the keychain or user defaults is blocked. So when you check for a boolean value, it will return false... because it can't be found.


Solution?

You could use something other than a bool, this way you can check for nil OR the value stored there. Since it's not ideal now that bool returns false for both false and nil in user defaults. If you store a String you'll get 3 options. "true", "false" and nil. Use nil to determine if you have access to user defaults or not.

Alternatively, don't use UserDefaults. Write to a different file instead.

It would be great if this feature was opt-in, or at the very least opt-out. It's a poorly implemented feature to be sure, and I'm sure has possibly caused thousands of dollars worth of damage at this point.

Upvotes: 1

jeremy ryner
jeremy ryner

Reputation: 15

This is an issue with iOS 15 SDK, Xcode 13... someone report it.

Check here: https://github.com/firebase/firebase-ios-sdk/issues/8695 & check here: https://developer.apple.com/forums/thread/685685

Upvotes: 0

Related Questions