1

I'm trying to write the contents of an array to NSUserDefaults, but the app hangs when I call setObject:withKey with the array as the object. Here's the relevant code:

class Contact: NSObject {
    var name:String = ""
    var number:String = ""
}

var contacts:[Contact]?

contacts = [Contact]()

let contact = Contact()
contact.name = "Joe"
contact.number = "123-4567"
contacts.append(contact)

let defaults = NSUserDefaults.standardUserDefaults()
// Never returns from this when I step over it in the debugger
defaults.setObject(contacts, forKey: "contacts")
defaults.synchronize()

What am I doing wrong?

Epsilon
  • 1,016
  • 1
  • 6
  • 15
  • 1
    Calling `defaults.synchronize()` is unnecessary in this case (as it is in most). Please let the cfprefsd daemon decide when to do the saving itself. – Jon Shier Dec 11 '14 at 23:08

1 Answers1

2

Not sure exactly how it works on OS X, but if it's anything like it is on iOS, you can't store custom classes in NSUserDefaults, only Strings, Ints, Data, etc... so one work around is to convert your array to NSData and then store it as data and when you retrieve it cast it to be [Contact]. It may look something like this:

    let data = NSKeyedArchiver.archivedDataWithRootObject(contacts)
    let defaults = NSUserDefaults.standardUserDefaults()
    // Storing the data
    defaults.setObject(data, forKey: "contacts")

    // Retrieving the data
    if let data = defaults.objectForKey("contacts") as? NSData {
        if let contacts = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? [Contact] {
            // Now you have your contacts
        }
    }

However, if you are storing large amounts of data, you should probably consider other forms of data management.

Ian
  • 12,538
  • 5
  • 43
  • 62