title: Simple persistent storage in Swift
body: <p>I have an array of objects each with a number of properties. Here is some sample data taken by looping through the array of objects:</p>
  
  <pre><code>Name = Rent
  Default Value 750
  This Months Estimate = 750
  Sum Of This Months Actuals = 0
  Risk Factor = 0.0
  Monthly Average = 750.0
  --------------
  Name = Bills
  Default Value 250
  This Months Estimate = 170
  Sum Of This Months Actuals = 140
  Risk Factor = 0.0
  Monthly Average = 190.0
  --------------
  Name = Food
  Default Value 240
  This Months Estimate = 200
  Sum Of This Months Actuals = 95
  Risk Factor = 0.0
  Monthly Average = 190.0
  --------------
  Name = Lunches
  Default Value 100
  This Months Estimate = 150
  Sum Of This Months Actuals = 155
  Risk Factor = 0.899999976158142
  Monthly Average = 190.0
  </code></pre>
  
  <p>Its very little data so I want to avoid using core data. I need to be able to persist save the array then open it again and be able to loop through it. I was hoping to use a simple solution like NSUserDefaults or NSKeyedArchiver but in Swift I can get neither to work with this type of array (I've been going through documentation and forums and examples online for 24 hours now...)</p>
  
  <p>How would you recommend I persist save an array of objects like the above? OR maybe persist saving this type of array is bad practice?</p>
  
  <p>Thanks in advance for your help!</p>
  
  <p>Adding the object class:</p>
  
  <pre><code>class costCategory : NSObject {
      var name : String
      var defaultValue : Int
      var thisMonthsEstimate : Int
      var sumOfThisMonthsActuals : Int
      var riskFactor : Float
      var monthlyAverage : Float
  
  
      init (name:String, defaultValue:Int, thisMonthsEstimate:Int, sumOfThisMonthsActuals:Int, riskFactor:Float, monthlyAverage:Float) {
          self.name = name
          self.defaultValue = defaultValue
          self.thisMonthsEstimate = thisMonthsEstimate
          self.sumOfThisMonthsActuals = sumOfThisMonthsActuals
          self.riskFactor = riskFactor
          self.monthlyAverage = monthlyAverage
      }
  
  }
  </code></pre>
  
  <p>If I try to save the array to NSUserDefaults I'm getting the error:</p>
  
  <pre><code>Property list invalid for format: 200 (property lists cannot contain objects of type 'CFType')
  </code></pre>
  
  <p>I have tried using inheriting from the NSCoder class but I get an error which Im not able to resolve, as below:</p>
  
  <pre><code>class costCategory : NSObject, NSCoder {
      var name : String
      var defaultValue : Int
      var thisMonthsEstimate : Int
      var sumOfThisMonthsActuals : Int
      var riskFactor : Float
      var monthlyAverage : Float
  
  
      init (name:String, defaultValue:Int, thisMonthsEstimate:Int, sumOfThisMonthsActuals:Int, riskFactor:Float, monthlyAverage:Float) {
          self.name = name
          self.defaultValue = defaultValue
          self.thisMonthsEstimate = thisMonthsEstimate
          self.sumOfThisMonthsActuals = sumOfThisMonthsActuals
          self.riskFactor = riskFactor
          self.monthlyAverage = monthlyAverage
      }
  
  
  
      // MARK: NSCoding
  
      required convenience init(coder decoder: NSCoder) {
          self.init() //Error here "missing argument for parameter name in call
          self.name = decoder.decodeObjectForKey("name") as String
          self.defaultValue = decoder.decodeIntegerForKey("defaultValue")
          self.thisMonthsEstimate = decoder.decodeIntegerForKey("thisMonthsEstimate")
          self.sumOfThisMonthsActuals = decoder.decodeIntegerForKey("sumOfThisMonthsActuals")
          self.riskFactor = decoder.decodeFloatForKey("riskFactor")
          self.monthlyAverage = decoder.decodeFloatForKey("monthlyAverage")
  
      }
  
      func encodeWithCoder(coder: NSCoder) {
          coder.encodeObject(self.name, forKey: "name")
          coder.encodeInt(Int32(self.defaultValue), forKey: "defaultValue")
          coder.encodeInt(Int32(self.thisMonthsEstimate), forKey: "thisMonthsEstimate")
          coder.encodeInt(Int32(self.sumOfThisMonthsActuals), forKey: "sumOfThisMonthsActuals")
          coder.encodeFloat(self.riskFactor, forKey: "riskFactor")
          coder.encodeFloat(self.monthlyAverage, forKey: "monthlyAverage")
  
      }
  }
  </code></pre>