1

I'm not sure how to use the new UserDefaults class with the new Swift3 changes.

I had this code prior to the migration to swift3 which successfully retrieved the data stored in the userDefaults:

if NSUserDefaults.standardUserDefaults().objectForKey("profileArray") != nil {    
    profileArray = NSUserDefaults.standardUserDefaults().objectForKey("profileArray") as! [String]
}

With the migration to swift3 the code is now:

if UserDefaults.standard.object(forKey: "profileArray") != nil {        
   profileArray = UserDefaults.standard.object(forKey: "profileArray")!  as! [NSString]
}

The new syntax makes sense but when I run the project the data that was previously stored in the user default seems to be gone.
The userdefault.standard... is now returning empty/nil.

How do I retrieve the data that was stored prior to the swift3 migration?

Appreciate the help with moving to swift3!

  • 1
    Is it possible the namespace of your app changed? Depending on your settings it may have changed some of those settings, or the defaults may have changed. – GetSwifty Oct 03 '16 at 22:40
  • 5
    It's _highly_ likely this is not a Swift 3 issue. – tktsubota Oct 04 '16 at 00:10
  • @PEEJWEEJ I didn't explicitly change anything. Could that have changed during the conversion? – The App Lady Oct 04 '16 at 00:29
  • @tktsubota this isn't a helpful response. Please explain why this is *highly* unlikely. The data was stored and retrieved successfully just prior to conversion. After conversion from swift 2.x to swift 3 the values maintained for the key are coming back null – The App Lady Oct 04 '16 at 00:32
  • Swift is the language itself, so it's very unlikely that is the cause. It likely has to do with what @PEEJWEEJ mentioned. There's more than just Swift being updated here: iOS changed, Xcode changed. You haven't isolated the issue enough to where you know only Swift is the problem, and there's little chance it is. – tktsubota Oct 04 '16 at 00:40
  • @tktsubota how do I determine if a namespace was changed? It's this something that is known to happen during a conversion? – The App Lady Oct 04 '16 at 00:42
  • How are you instantiating your user defaults? Do you use `UserDefaults.standard` (or what used to be `NSUserDefaults.standardUserDefaults()`)? – tktsubota Oct 04 '16 at 00:45
  • @tktsubota yes, i'm using 'NSUserDefaults.standardUserDefaults().setObject(x, forKey: "x")' to instantiate the defaults. But in swift3 it's no longer using NSx... something changed from swift 2.x to 3.0. – The App Lady Oct 04 '16 at 00:52
  • @PEEJWEEJ please see my updated question which includes examples of the code prior to swift 3 and after swift3. – The App Lady Oct 05 '16 at 02:15
  • Probably not a solution but your syntax is not very efficient – you retrieve the object from user defaults unnecessarily twice. I recommend optional binding and the dedicated method to get an array: `if let array = UserDefaults.standard.array(forKey: "profileArray") as? [String] { profileArray = array }` – vadian Oct 05 '16 at 06:30
  • Why is it being cast to NSString? that might be your problem. – GetSwifty Oct 05 '16 at 17:11
  • @vadian can you post this as an answer instead of a comment? Thanks! – The App Lady Oct 05 '16 at 17:12
  • @PEEJWEEJ the array named "profileArray" is type [NSSTRING] – The App Lady Oct 05 '16 at 17:13

2 Answers2

0

I don't know if that solves your problem, but your syntax is not very efficient – you retrieve the object from user defaults unnecessarily twice.

The recommended way is optional binding and the dedicated method to get an array:

if let array = UserDefaults.standard.array(forKey: "profileArray") as? [String] { 
   profileArray = array 
}

Im Swift use always String rather than NSString unless you have no choice.

vadian
  • 274,689
  • 30
  • 353
  • 361
  • thanks. i agree on the efficiency but the fact remains, that the code prior to the migration worked and retrieved the data successfully and after the migration to swift3 the data that was stored in the userDefaults seems lost. – The App Lady Oct 05 '16 at 18:42
  • i found this [link] (http://stackoverflow.com/questions/37798426/using-nsuserdefaults-with-xcode-8-and-ios-10) and this seems to get close to my issue. in one of the comments a user stated that after the migration to swift3 the data in the defaults would persist...but my example seems to indicate the data does not persist after the migration. have hundreds of users using my app and i need to figure out to retrieve the NSUserDefault data that was stored under the swift2.2 version of my app. – The App Lady Oct 05 '16 at 19:03
0

I have finally figured this out. The userDefaults weren't "cleared". but the userDefaults are specific to a device. so with the migration to xcode8 the iOS simulators were also upgraded....and these are technically new devices where userDefaults had never been captured.

I proved this theory by adding a simulator (you can go back and re-install iOS 9.x simulators) and this worked.

I also tested on a real device using iOS 9.x & the new swift 3 code and the defaults persisted on that device.

So problem solved! :)