how to save and read array of array in NSUserdefaults in swift? how to save and read array of array in NSUserdefaults in swift? swift swift

how to save and read array of array in NSUserdefaults in swift?


The question reads "array of array" but I think most people probably come here just wanting to know how to save an array to UserDefaults. For those people I will add a few common examples.

String array

Save array

let array = ["horse", "cow", "camel", "sheep", "goat"]let defaults = UserDefaults.standarddefaults.set(array, forKey: "SavedStringArray")

Retrieve array

let defaults = UserDefaults.standardlet myarray = defaults.stringArray(forKey: "SavedStringArray") ?? [String]()

Int array

Save array

let array = [15, 33, 36, 723, 77, 4]let defaults = UserDefaults.standarddefaults.set(array, forKey: "SavedIntArray")

Retrieve array

let defaults = UserDefaults.standardlet array = defaults.array(forKey: "SavedIntArray")  as? [Int] ?? [Int]()

Bool array

Save array

let array = [true, true, false, true, false]let defaults = UserDefaults.standarddefaults.set(array, forKey: "SavedBoolArray")

Retrieve array

let defaults = UserDefaults.standardlet array = defaults.array(forKey: "SavedBoolArray")  as? [Bool] ?? [Bool]()

Date array

Save array

let array = [Date(), Date(), Date(), Date()]let defaults = UserDefaults.standarddefaults.set(array, forKey: "SavedDateArray")

Retrieve array

let defaults = UserDefaults.standardlet array = defaults.array(forKey: "SavedDateArray")  as? [Date] ?? [Date]()

Object array

Custom objects (and consequently arrays of objects) take a little more work to save to UserDefaults. See the following links for how to do it.

Notes

  • The nil coalescing operator (??) allows you to return the saved array or an empty array without crashing. It means that if the object returns nil, then the value following the ?? operator will be used instead.
  • As you can see, the basic setup was the same for Int, Bool, and Date. I also tested it with Double. As far as I know, anything that you can save in a property list will work like this.


Just to add on to what @Zaph says in the comments.

I have the same problem as you, as to know, the array of String is not saved. Even though Apple bridges types such as String and NSString, I wasn't able to save an array of [String] neither of [AnyObject].

However an array of [NSString] works for me.

So your code could look like that :

var key = "keySave"var array1: [NSString] = [NSString]()array1.append("value 1")array1.append("value 2")//savevar defaults = NSUserDefaults.standardUserDefaults()defaults.setObject(array1, forKey: key)defaults.synchronize()//readif let testArray : AnyObject? = defaults.objectForKey(key) {    var readArray : [NSString] = testArray! as [NSString]}

Note that I created an array of NSString and not a dictionary. I didn't check if it works with a dictionary, but probably you will have to define the things as [NSString : NSString] to have it working.

EDIT

Re-reading your question and your title, you are talking of array of array. I think that as long as you stay with NSString, an array of array will work. However, if you think my answer is irrelevant, just let me know in the comments and I will remove it.


Here is an example of reading and writing a list of objects of type SNStock that implements NSCoding - we have an accessor for the entire list, watchlist, and two methods to add and remove objects, that is addStock(stock: SNStock) and removeStock(stock: SNStock).

import Foundationclass DWWatchlistController {  private let kNSUserDefaultsWatchlistKey: String = "dw_watchlist_key"  private let userDefaults: NSUserDefaults  private(set) var watchlist:[SNStock] {    get {      if let watchlistData : AnyObject = userDefaults.objectForKey(kNSUserDefaultsWatchlistKey) {        if let watchlist : AnyObject = NSKeyedUnarchiver.unarchiveObjectWithData(watchlistData as! NSData) {          return watchlist as! [SNStock]        }      }      return []    }    set(watchlist) {      let watchlistData = NSKeyedArchiver.archivedDataWithRootObject(watchlist)      userDefaults.setObject(watchlistData, forKey: kNSUserDefaultsWatchlistKey)      userDefaults.synchronize()    }  }  init() {    userDefaults = NSUserDefaults.standardUserDefaults()  }  func addStock(stock: SNStock) {    var watchlist = self.watchlist    watchlist.append(stock)    self.watchlist = watchlist  }  func removeStock(stock: SNStock) {    var watchlist = self.watchlist    if let index = find(watchlist, stock) {      watchlist.removeAtIndex(index)      self.watchlist = watchlist    }  }}

Remember that your object needs to implement NSCoding or else the encoding won't work. Here is what SNStock looks like:

import Foundationclass SNStock: NSObject, NSCoding{  let ticker: NSString  let name: NSString  init(ticker: NSString, name: NSString)  {    self.ticker = ticker    self.name = name  }  //MARK: NSCoding  required init(coder aDecoder: NSCoder) {    self.ticker = aDecoder.decodeObjectForKey("ticker") as! NSString    self.name = aDecoder.decodeObjectForKey("name") as! NSString  }  func encodeWithCoder(aCoder: NSCoder) {    aCoder.encodeObject(ticker, forKey: "ticker")    aCoder.encodeObject(name, forKey: "name")  }  //MARK: NSObjectProtocol  override func isEqual(object: AnyObject?) -> Bool {    if let object = object as? SNStock {      return self.ticker == object.ticker &&        self.name == object.name    } else {      return false    }  }  override var hash: Int {    return ticker.hashValue  }}

Hope this helps!