sunshinejr / SwiftyUserDefaults

Modern Swift API for NSUserDefaults
http://radex.io/swift/nsuserdefaults/static
MIT License
4.85k stars 366 forks source link

Value not stored until second try #198

Open pgawlowski opened 5 years ago

pgawlowski commented 5 years ago

I am trying to store value (Date) in user defaults. This is the key static let firstActivityDate = DefaultsKey<Date?>("firstActivityDate And code responsible for storing func setActivityDate() { if Defaults[AppRateDefaults.firstActivityDate] == nil { Defaults[AppRateDefaults.firstActivityDate] = Date() } } I have to run it twice (in two sessions of application) to correctly store value. First attempt is showing value as long as app is up and running. After turning off and running once again it's once again empty. After second attempt value persists.

Edit: It seems to be connected with thread. After running this part of code on the main it seems to work fine.

mman commented 5 years ago

This looks like a classic case of NSUserDefaults not storing the value to the underlying storage. NSUserDefaults are persisted only when you manually call synchronize - which is not needed and not recommended, and at certain times during the lifecycle of the app automatically.

If you terminate the app (for example) by re-running it in the simulator the modified defaults are never persisted. Try sending the app to the background and then re-running it and see if it works.

jojo91 commented 4 years ago

I have the same issue, not exactly the same issue. For my part it's kinda random. Sometimes it works and sometimes not. I've tried to call the synchronize method even if it's not recommanded but it doesn't change anything. I've also tried to execute on the main thread but it change nothing. Have you any idea to resolve my issue ?

sunshinejr commented 4 years ago

Hey @jojo91, can you share how do you call SwiftyUserDefaults? Can you also specify which version do you use?

One thing to try would be to just use UserDefaults instead and see if the problem persists.

jojo91 commented 4 years ago

Hi @sunshinejr, i'm using the 4.0 version of the library. Here is my code :

`

public static var dataKey: DefaultsKey<Data?> {
    return DefaultsKey<Data?>("data")
}

public static var stringKey: DefaultsKey<String?> {
    return DefaultsKey<String?>("string")
}

public static func saveData(myData: MyData, myString: String) -> Promise<Void> {
    return serialize(object: myData) // return an optional Data object
        .then { optionalData -> Promise<Void> in
            guard let data = optionalData else { return Promise(error: Error) }

            Defaults[dataKey] = data
            Defaults[stringKey] = myString
            return Promise()
    }
}

`

jojo91 commented 4 years ago

I've tried using only UserDefaults and I have the same issue.

sunshinejr commented 4 years ago

@jojo91 Yeah, this is really hard to debug. This might be a synchronization issue - try to only save/fetch on one queue.

jojo91 commented 4 years ago

You mean on a specific queue or on the main queue ?

sunshinejr commented 4 years ago

I suspect that you might be accessing the same property from multiple threads - so I would make sure that you are setting/fetching it from the same queue (can be main).