10

There seems to be a strange issue with iOS Playgrounds where NSUserDefaults always returnsnil instead of the actual value.

In an iOS Playground the last line wrongly returns nil.

import UIKit

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("This is a test", forKey: "name")
let readString = defaults.objectForKey("name")

In an OSX Playground the last line correctly returns "This is a test".

import Cocoa

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("This is a test", forKey: "name")
let readString = defaults.objectForKey("name")

Any idea why this is? Bug?

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
Daniel
  • 436
  • 3
  • 14

5 Answers5

7

That's not really a bug..... NSUserDefaults is tied to the iOS sandbox environment. Playgrounds doesn't run in this environment. Hence why you won't be able to write files to disk. If you run this code in the application when running via the simulator or device, you'll have access to the sandbox environment and NSUserDefaults will return a proper reference. I do see though that I get a proper reference in playgrounds and can set and get values, so there has to be something else going on here. I just wouldn't rely on this being the way to test this type of functionality due to the nature.

Notice what happens when I synchronize the store.

Example

The value becomes nil due to the fact that there's nothing to persist against.

TheCodingArt
  • 3,436
  • 4
  • 30
  • 53
  • 1
    This works for me in an iOS playground: `let readString = defaults.objectForKey("name") as? String`. – zaph Jul 03 '15 at 15:36
  • I've updated my answer to reflect what I saw in Xcode 6. Just out of curiosity, are you using the Xcode 7 beta? I really wouldn't rely on read/write/storage functionality to work properly in the playground environment. The playground environment is meant for more independent modular code rather persistence code. – TheCodingArt Jul 03 '15 at 15:38
3

For what it’s worth, the following code works fine in iOS Playground version 1.6.1 (Swift 4):

import Foundation

let defaults = UserDefaults.standard
defaults.set("This is a test", forKey: "name")
let readString = defaults.string(forKey: "name")
print(readString!)

prints:

This is a test
Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
  • I tried this yesterday and it did work 100% with no issues. I run the exact same code today and it doesn’t work. The value does’t set so it returns nil. Any ideas? – Junaid Mar 23 '18 at 09:47
1

The code works correctly in Xcode 6.4 but fails in Xcode 7.0 beta (7A120f).

  1. Betas are known to have bugs.
  2. File a bug report: http://bugreport.apple.com
zaph
  • 111,848
  • 21
  • 189
  • 228
0

In Xcode 9.2 for iOS it's currently even working that the UserDefaults are saved between reruns of the playground. That was at first irritating me, because I expected that after each stop the UserDefaults would be cleaned, like they were obviously before. So, a warning: UserDefaults are now persisted between reruns, better keep that in mind when searching for bugs, there may be side effects!

Jan
  • 1,032
  • 11
  • 26
0

Not work if I use import UIKit, the code that works importing Cocoa library;

import Cocoa

let defaults = UserDefaults.standard

defaults.set("This is a test", forKey: "name")
let readString = defaults.object(forKey: "name")
Akif
  • 73
  • 5