-2

I have the following:

                let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
                let phone = defaults.objectForKey("phone") as String                   
                println(phone)       
                defaults.removeObjectForKey("phone")
                println("phone2\(phone)")

The prints are showing the same result despite attempted unset, results such as "5" or "6".

pnuts
  • 58,317
  • 11
  • 87
  • 139

2 Answers2

4

You're printing the variable phone, removeObjectForKey is not going to update the variable phone. So, you've to get the updated value from NSUserdefaults,

let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("Hello", forKey: "phone")
let phone = defaults.objectForKey("phone") as String
// This will save your value in `phone`
// Do not synchronize after removing the key, if you want 'value' for your key 'phone' after your application terminated
defaults.synchronize() 
println(phone)
defaults.removeObjectForKey("phone")

// Get the updated value,
let updatedPhone = defaults.objectForKey("phone") as String?
// This will save nil in your `phone` key, make sure that what you want
defaults.synchronize() 
println("phone2\(updatedPhone)")

Like @Lyndshey said, you don't have to Synchronize, because it'll happen automatically at periodic intervals. But if you can't wait for it and your app is going to exit, you can Synchronize, but really this is performance issue.

Please check Apple Documentation, and also check this Stackoverflow answer

Community
  • 1
  • 1
arthankamal
  • 6,341
  • 4
  • 36
  • 51
  • Yes, it'll work. But if you want to have the value, after application terminated, then you need to `synchronize()` it. – arthankamal Jan 16 '15 at 05:28
  • I do want it after termination. How can I put the synchronize() above a class? – James Shelton Jan 16 '15 at 05:29
  • or make a new class above the main ones... like this ? class syncit{ let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults() defaults.synchronize() } – James Shelton Jan 16 '15 at 05:30
  • @JamesShelton I think arthankamal's right all the way around on this answer. You don't need to synchronize like Bluehound's recommending. As Apple says in their docs about synchronize: "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." – Lyndsey Scott Jan 16 '15 at 05:34
  • Lyndsey, how do you know how "frequently" – James Shelton Jan 16 '15 at 05:38
  • 1
    @arthankamal Your updated answer is going entirely against Apple's recommendation. Really the OP should just be calling synchronize in applicationWillTerminate in the appDelegate. – Lyndsey Scott Jan 16 '15 at 05:41
  • 1
    @LyndseyScott, you are right, I've given the reference also, but now its really upto James Shelton. – arthankamal Jan 16 '15 at 05:50
2

Answer is simple. You are printing the previously assigned phone variable. You need to again retrieve the value from NSUserDefaults to check whether it exists or not.

let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
var phone = defaults.objectForKey("phone") as String                   
println(phone)       
defaults.removeObjectForKey("phone")
if let phone = defaults.objectForKey("phone") as? String
{
        println("phone2\(phone)")
}
else
{
        println("Value is nil")
}
Midhun MP
  • 103,496
  • 31
  • 153
  • 200
  • I went through with a search and changed all to let to this: var defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults(). But, I am still not getting a reset. – James Shelton Jan 16 '15 at 04:53
  • Do I need to change let phone to var phone also? – James Shelton Jan 16 '15 at 04:53
  • it knows what phone is still even with let defaults and var phone being set everywhere – James Shelton Jan 16 '15 at 05:00
  • @JamesShelton: above code won't give that result. That if condition never work (because phone is nil). I checked it in my sample app before posting it. – Midhun MP Jan 16 '15 at 05:02
  • @JamesShelton arthankamal's answer seems to be more like what you're looking for in this particular case... I'd suggest trying that out too. – Lyndsey Scott Jan 16 '15 at 05:04
  • @LyndseyScott: What is the difference between these two ? One is using optional and another one is trying to unwrap. What else is the difference ? – Midhun MP Jan 16 '15 at 05:05
  • There are a few issues. (1) You never set an initial value for "phone" so your code executes with an error but more importantly, (2) once the object is removed, the OP wants to print that it's "nil". There's obviously no need to unwrap the optional in order to do that... in fact you *can't* unwrap the optional in order to do that. arthankamal's accomplishes everything the OP was looking for. – Lyndsey Scott Jan 16 '15 at 05:09
  • About the first one I set the initial value, please read the answer again. 2nd part is okay and I updated my answer – Midhun MP Jan 16 '15 at 05:11
  • @MidhunMP No, you're still missing this line: `defaults.setObject("Hello", forKey: "phone")` – Lyndsey Scott Jan 16 '15 at 05:12
  • @LyndseyScott: The OP is done that in his code why should I do that ? In my sample app I'm doing that. From OP's question he clearly saying that he is getting the value twice, so he is assigning that somewhere else (So why I need to add that my part) – Midhun MP Jan 16 '15 at 05:14
  • @MidhunMP Whether you add that code or not, that's all irrelevant really... Like I said, *most importantly*, the point is that the OP wanted to print the value of "phone" once `defaults.removeObjectForKey("phone")` was executed and your code does not do that. arthankamal's does. – Lyndsey Scott Jan 16 '15 at 05:16
  • @MidhunMP OK, just saw it. Unwrapping the optional doesn't seem to serve any extra purpose, but yes, your answer's right now. – Lyndsey Scott Jan 16 '15 at 05:18
  • @LyndseyScott: I don't want to change that unwrapping (Don't want to play with optionals) also changing that will make my answer exact duplicate of another answer. So don't want to do that. There are so many ways. So can't say it's wrong and in no document Apple mentioned that it's wrong. Even apple's playground they use the above mentioned ways. – Midhun MP Jan 16 '15 at 05:25
  • @MidhunMP Never hurts to have more than one correct answer. – Lyndsey Scott Jan 16 '15 at 05:30
  • I would vote this up but I do not have 15. I need to change one more let to var. – James Shelton Jan 16 '15 at 06:14
  • @JamesShelton: It's ok, happy to hear that it worked – Midhun MP Jan 16 '15 at 06:31