0

In a class FirstViewController, I add an array with key rentedItems to the NSUserDefaults in the following lines:

let itemArray = [Item]()
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
prefs.setObject(itemArray, forKey: "rentedItems")

Then, in another class SecondViewController, I try

var item: Item?
var prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()    

func confirmPressed() {
    prefs.arrayForKey("rentedItems")?.append(item)
}

This then gives the following error: Cannot use mutating member on immutable value: function call returns immutable value. I saw a solution in SO here that gave me an idea of the problem, but NSUserDefaults being a default iOS class, I can't use the same solution as there. Any ideas?

Community
  • 1
  • 1
Suleiman
  • 63
  • 3

2 Answers2

1

You will need to archive Your Custom Object Array into NSData then save it to NSUserDefaults and retrieve it from NSUserDefaults and unarchive it again. You can archive it like this:

var userDefaults = NSUserDefaults.standardUserDefaults()
let encodedData = NSKeyedArchiver.archivedDataWithRootObject(itemArray)
userDefaults.setObject(encodedData, forKey: "rentedItems")
userDefaults.synchronize()

And unarchive it like this

let decoded  = userDefaults.objectForKey("rentedItems") as! NSData
let itemArray = NSKeyedUnarchiver.unarchiveObjectWithData(decoded) as! [Item]
derdida
  • 14,784
  • 16
  • 90
  • 139
  • Oh, I guess you're right. This is an array of custom objects. In that case, as you say, you'll need to use NSKeyedArchiver. Further, the Item object will have to be a subclass of `NSObject`, not `AnyObject`. – Duncan C Aug 01 '16 at 18:10
  • "the Item object will have to be a subclass of `NSObject`" - Oh yes, thats importend here. – derdida Aug 01 '16 at 18:12
  • That should have been "the item will have to be a subclass of NSObject". "item object" was an editing error. – Duncan C Aug 01 '16 at 19:04
1

You can't directly modify an array from defaults. Instead make a copy, and modify that. You can save that array to defaults afterwards. Simply try like this:

var array = prefs.arrayForKey("rentedItems")?.mutableCopy
array.append(item) 
NightFury
  • 13,436
  • 6
  • 71
  • 120
  • 1
    There's no need for the mutableCopy call in Swift. Swift determines mutability through the use of `var` rather than `let`. Simply by using `var array = prefs.arrayForKey("rentedItems")` The result is made mutable – Duncan C Aug 01 '16 at 18:03