2

I am new to swift and trying to store NSMutableArray in Userdefaults. Here is what I am doinig :

//to save aaray in user defaults
var set:NSMutableArray = NSMutableArray(objects: self.listId)
  self.saveListIdArray(set)

func saveListIdArray(_ params: NSMutableArray = []) {
let defaults = UserDefaults.standard
defaults.set(params, forKey: "ArrayKey")
defaults.synchronize()

}

//to get array from user default
func getUserDefaultKeyForAllObject(key userDefaultsKey: String) -> NSMutableArray {
let array = UserDefaults.standard.object(forKey: NSUserDefaultsKey.LIST_ID_ARRAY) as! NSMutableArray
print(array)
return array

}

App crashes with "fatal error: unexpectedly found nil while unwrapping an Optional value" exception.

Ignore the way I ask the question, help me out here.

Thank you.

Hamish
  • 78,605
  • 19
  • 187
  • 280
Sumeet Purohit
  • 657
  • 1
  • 7
  • 16
  • 1. Don't use `NSMutableArray` in Swift. Use a Swift array. 2. What kinds of objects are in the array? – rmaddy May 12 '17 at 14:34

3 Answers3

4

Try converting to NSData then storing to nsuserdefaults like below

func saveListIdArray(_ params: NSMutableArray = []) {
let data = NSKeyedArchiver.archivedData(withRootObject: params) 

UserDefaults.standard.set(data, forKey: "test")
UserDefaults.standard.synchronize()
}

For retrieving the data use

if let data = UserDefaults.standard.object(forKey: "test") as? Data {
    if let storedData = NSKeyedUnarchiver.unarchiveObject(with: data) as? NSMutableArray 
{
            // In here you can access your array
}
}
DHEERAJ
  • 1,478
  • 12
  • 32
1

You are force unwrapping the NSMutableArray for a key. Don't force unwrap when you try to get the value from a dictionary or UserDefault for a key because there may be a chance that the value does not exist for that key and force unwrapping will crash your app.

Do this as:

 //to get array from user default
 if  let array = UserDefaults.standard.object(forKey:"ArrayKey") as? NSMutableArray
    print(array)
  }
1

I have 2 possible reasons for this:

  1. You need to be 100% sure that you are retrieving array with the same key as you save it with. In your code you are saving the array with "ArrayKey" but retrieving it with NSUserDefaultsKey.LIST_ID_ARRAY, are you sure this is the same string?
  2. What datatype is self.listId? If it's a custom class then you need to make that class conform to the nscoding protocol, then encode it to Data and save that to the userDefaults (Save custom objects into NSUserDefaults)

A 3rd reason is that you are trying to get an object from the defaults without ever writing anything to it. Try changing

let array = UserDefaults.standard.object(forKey: NSUserDefaultsKey.LIST_ID_ARRAY) as! NSMutableArray
print(array)
return array

to

if let array = UserDefaults.standard.object(forKey: "ArrayKey") as? NSMutableArray {
   print(array)
   return array
}
else {
   return NSMutableArray()
}
Community
  • 1
  • 1
SveinnV
  • 184
  • 4
  • Ok, your first point is full filled i.e. I am using the same key. Secondly, list is is string which I am storing in array coz I need to store multiple listIds in the array depending on the items user selects. – Sumeet Purohit May 12 '17 at 10:15
  • OK, so it seems there is a 3rd reason: You are trying to access the object from the userdefaults before you actually store anything. 'UserDefaults.standard.object(forKey: NSUserDefaultsKey.LIST_ID_ARRAY)' is returning nil and you are trying to cast that to NSMutableArray which will crash – SveinnV May 12 '17 at 10:32