1

I am trying to save an string array using NSUserDefaults with swift. I have searched around and believe that i have to use [NSString] not [String] however the app still crashes with error

fatal error: unexpectedly found nil while unwrapping an Optional value

I can not see what i am doing wrong as it is working perfectly fine saving ints and strings. Here is my code for my data singleton and NSUserDefaults.

struct DefaultsKeys
{
  static let myString  = "myString"
  static let myInt  = "myInt"
  static let myArray = "myArray"

}



class DataContainerSingleton
{
  static let sharedDataContainer = DataContainerSingleton()


  var myString: String?
  var myInt: Int?
  var myArray:[NSString]?

/* I have also tried:
  var myArray:[NSString] = [NSString]() */



  var goToBackgroundObserver: AnyObject?

  init()
  {
    let defaults = NSUserDefaults.standardUserDefaults()


    myString = defaults.objectForKey(DefaultsKeys.myString) as! String?
    myInt = defaults.objectForKey(DefaultsKeys.myInt) as! Int?
    myArray = defaults.objectForKey(DefaultsKeys.myArray) as! [NSString]?



    goToBackgroundObserver = NSNotificationCenter.defaultCenter().addObserverForName(
      UIApplicationDidEnterBackgroundNotification,
      object: nil,
      queue: nil)
      {
        (note: NSNotification!) -> Void in
        let defaults = NSUserDefaults.standardUserDefaults()

        defaults.setObject( self.myString, forKey: DefaultsKeys.my)
        defaults.setObject( self.myInt, forKey: DefaultsKeys.myInt)
        defaults.setObject( self.myArray, forKey: DefaultsKeys.myArray)


        defaults.synchronize()
    }
  }
}
Matt
  • 688
  • 5
  • 15
  • On which line does the error occur? – jtbandes Jul 23 '15 at 04:54
  • Ok. So i think the problem is not with the implementation of NSUserDefaults but with accessing the values elsewhere in the app. It would make my life a whole lot easier if i could intialize the array in the data container instead of making it optional. Is there a way to make this work? – Matt Jul 23 '15 at 05:13

2 Answers2

2
        <!-- language: swift -->

        //declare and initiate the array        
        var sample_array : NSMutableArray! = []
        //use mutable array to add data

        //variable to store value in array
        var say: String! =  "Hello"

        //add values in array
        sample_array.addObject("hello")
        //or
        //sample_array.addObject(say)

        /*
        //you can also save values in array like this
        var sample_array: Array<String> = []
        var say: String! =  "Hello"
        sample_array = ["Qwerty"]
        sample_array.insert(say, atIndex: 1)
        println(sample_array)
        */

        //archive and saving data 
        let data = NSKeyedArchiver.archivedDataWithRootObject(sample_array)
        NSUserDefaults.standardUserDefaults().setObject(data, forKey: "array_key")
        NSUserDefaults.standardUserDefaults().synchronize()

        //unarchive and getting data
        if let data = NSUserDefaults.standardUserDefaults().objectForKey("array_key") as? NSData {
        stopover_array = NSKeyedUnarchiver.unarchiveObjectWithData(data)  as NSMutableArray
            }
developerr
  • 35
  • 1
  • 9
1

Problem is the code:

myString = defaults.objectForKey(DefaultsKeys.myInt) as! String?
myInt = defaults.objectForKey(DefaultsKeys.myInt) as! Int?
myArray = defaults.objectForKey(DefaultsKeys.myArray) as! [NSString]?

as! means unwraping an optional value, that's why your app crashed with error

fatal error: unexpectedly found nil while unwrapping an Optional value

if defaults.objectForKey(DefaultsKeys.myInt) is nil, then unwrapping nil is not allowed. You should use

myString = defaults.objectForKey(DefaultsKeys.myInt) as? String

instead.

icodesign
  • 876
  • 1
  • 6
  • 12
  • I have tried initializing the array as shown in my code thats commented out below the property declarations but it says that i have to use as! to convert anyobject? to [NSString]. I am confused as i declared it as type [NSString] and intialized as [NSString](). Any idea what is going on? – Matt Jul 23 '15 at 05:20
  • If you declare the property as non-optionals, you should use `as!`. – icodesign Jul 23 '15 at 05:28
  • Ok so ive managed to get it working leaving it as an optional and adding a bunch of value checks into my code. – Matt Jul 23 '15 at 05:34