1

I have a global settings variable (SettingsVariable.settingOne) that is changed by the user during the apps runtime. I want to make the users change permanent, but at the moment every time the app is then reloaded it reverts to the original values e.g. user changes value to false, but then when the app is rerun the variables value changes back to the original value.

When the value is changed the following code is called (swift 2):

NSUserDefaults.standardUserDefaults().setBool(false, forKey: "settingOne")

and when the app is closed:

func applicationWillTerminate(application: UIApplication) {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.

    NSUserDefaults.standardUserDefaults().setBool(SettingsVariables.settingOne, forKey: "settingOne")
}

then once the app is opened again:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.

        NSUserDefaults.standardUserDefaults().boolForKey("settingOne")

        return true
}

But the value of settingOne keeps reverting back to the default value of 'true' set originally within the application.

SettingsVariables.settingOne is contained within a struct:

import UIKit

struct SettingsVariables {

    static var settingOne = true

}
R.Ham
  • 67
  • 1
  • 10

4 Answers4

1

Now Apple documentation suggests to use CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication) instead of calling UserDefaults.standard.synchronize() which is marked as a deprecated method.

Vladimir Kaltyrin
  • 621
  • 1
  • 4
  • 16
  • 1
    CFPreferencesAppSynchronize has been available since iOS 2.0, this is not news. And you don't need to call this either anyway. Please all have a look at [this answer](https://stackoverflow.com/a/40809748/2227743) which has excellent explanations. – Eric Aya Jul 13 '21 at 10:37
0

You need to give synchronize to save NSUserDefaults.

So your code must be

func applicationWillTerminate(application: UIApplication) {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.

    NSUserDefaults.standardUserDefaults().setBool(SettingsVariables.settingOne, forKey: "settingOne")
    NSUserDefaults.standardUserDefaults().synchronize()
}
Arasuvel
  • 2,971
  • 1
  • 25
  • 40
0

You have to synchronize the values NSUserDefaults.standardUserDefaults().synchronize()

Yogesh Mv
  • 1,041
  • 1
  • 6
  • 12
  • Thanks for the reply, I've added that to the code but it still isnt loading the changed value. – R.Ham Oct 20 '16 at 14:17
  • applicationWillTerminate method will only call when we kill the app from multiTasking. Try to add the save logic in "applicationDidEnterBackground" method. – Yogesh Mv Oct 20 '16 at 14:20
  • I have the coe in both the applicationWillTerminate and applicationDidEnterBackground methods but not working – R.Ham Oct 20 '16 at 14:21
  • in applicationWillTerminate method you are using "SettingsVariables.settingOne" value for saving in NSUserDefaults, if this method calls at last, then the NSUSerDefaults value will get overwrited. – Yogesh Mv Oct 20 '16 at 14:26
  • If you have value in NSUserDefaults then you have to update the SettingsVariables.settingOne value based on NSUserDefault value. I hope this could help you. – Yogesh Mv Oct 20 '16 at 14:33
-1

this what I use for getting element from NSUserDefaults , UserDataKey is just Enum

func userDataForKey(key: UserDataKey) -> String? {
    let userDefaults = NSUserDefaults.standardUserDefaults()
    if let value: AnyObject = userDefaults.objectForKey(key.rawValue) {
        return value as? String
    } else {
        return nil
    }
}

and this for saving

 func setUserData(value: AnyObject?, key: UserDataKey) -> () {
    let userDefaults = NSUserDefaults.standardUserDefaults()
    userDefaults.setObject(value, forKey: key.rawValue)
}
ivan123
  • 317
  • 2
  • 7