简体   繁体   中英

Xcode 9 simulator doesn't save userdefaults

Maybe it's the same issue as this one. But few of the solutions that I have tried don't work.

The simulator don't save userdefaults on Xcode Version 9.0 beta 6 (9M214v). I had Xcode 8 as well (together with 9) but removed it.

the code that I'm using:

UserDefaults.standard.setValue("1234567", forKey: "phone")
if let phone = UserDefaults.standard.value(forKey: "phone") as? String{
  //some code here
}

Additionally I have tried:

UserDefaults.standard.set("1234567", forKey: "phone")
if let phone = UserDefaults.standard.object(forKey: "phone") as? String{
  //some code here
} 

There are a lot of misunderstandings about what synchronize does and how user defaults are written. Before guessing at how things work, always check the current maintainer's commentary about it. He's pretty clear about things. His analogy to git is also somewhat useful, and see his notes about iOS 8 changes. NSUserDefaults changes way more than you would think it would for such an old piece of tech.

The short and long of it is that calling synchronize is almost never needed in a production app. (In fact, there's recurring discussion about deprecating and removing it.) As the docs note:

Because this method is automatically invoked at periodic intervals, use this method only if you cannot wait for the automatic synchronization (for example, if your application is about to exit) or if you want to update the user defaults to what is on disk even though you have not made any changes.

And even those cases mostly relate to macOS.

For applications running on iOS 9.3 and later / macOS Sierra and later, -synchronize is not needed (or recommended) even in this situation [synchronizing between processes], since Key-Value Observation of defaults works between processes now, so the reading process can just watch directly for the value to change. As a result of that, applications running on those operating systems should generally never call synchronize.

BUT.....

The usual problem people have with user defaults in the simulator is that they kill the app (hitting stop, restarting the app, crashing) before the write takes place. In production this generally isn't an issue. If you crash right around the time you're writing to user defaults, it's pretty likely you were in a poorly defined state anyway, so whether you wrote garbage, or wrote something good, or didn't write anything is all kind of a toss-up of what you would prefer. But when developing, program termination happens all the time, and often this leads to not writing out the user defaults.

Now one often-seems-to-work solution is to sprinkle synchronize all over the place. But for the most part that just slows your code down. If it works, fine. But in the majority of projects I've worked on, the real solution was just to take a breath before killing the app. It doesn't need a lot of time; just don't kill the app before it has a chance to write the thing you were saving before relaunching to check if it saved.

for me I was using a library from git
this library was removing all userDefaults.
As described in this answer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM