SwiftyUserDefaults icon indicating copy to clipboard operation
SwiftyUserDefaults copied to clipboard

Value not stored until second try

Open pgawlowski opened this issue 6 years ago • 8 comments

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.

pgawlowski avatar Jun 12 '19 13:06 pgawlowski

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.

mman avatar Jun 12 '19 13:06 mman

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 ?

jojo91 avatar Sep 17 '19 08:09 jojo91

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.

sunshinejr avatar Sep 17 '19 08:09 sunshinejr

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 avatar Sep 17 '19 12:09 jojo91

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

jojo91 avatar Sep 17 '19 13:09 jojo91

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

sunshinejr avatar Sep 17 '19 14:09 sunshinejr

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

jojo91 avatar Sep 17 '19 14:09 jojo91

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).

sunshinejr avatar Sep 17 '19 16:09 sunshinejr