2016-03-20 21 views
0

Ich erstelle eine schnelle App, die Benutzereinkäufe in Swift verfolgt. Es gibt eine Purchase-Klasse, und ich versuche, ein NSMutableArray davon in den Benutzerstandards zu speichern.Gespeicherte Arrays mit benutzerdefinierten Swift-Objekten können nicht abgerufen werden

Wenn ich gehe, um die Daten zu laden, nach dem ersten Drücken der App, um einen Speichervorgang auszulösen, wird der else immer ausgeführt. Das Abrufen der Ganzzahlmenge (die Daten für KEY_WEEKLY_AMOUNT) ist jedoch immer erfolgreich.

class UserDatas { 
static let sharedInstance = UserDatas() 
let defaults = NSUserDefaults.standardUserDefaults() 
let KEY_ARRAY_OF_PURCHASES = "KEY_ARRAY_OF_PURCHASES" 
let KEY_WEEKLY_AMOUNT = "KEY_WEEKLY_AMOUNT" 

var arrayOfUserPurchases:NSMutableArray = NSMutableArray() 
var weeklyAmount:Int = 0 


func saveTheDatas() { 

    let arrayOfArchivedDatas = NSKeyedArchiver.archivedDataWithRootObject(arrayOfUserPurchases) 
    defaults.setObject(arrayOfArchivedDatas, forKey: KEY_ARRAY_OF_PURCHASES) 

    defaults.setInteger(weeklyAmount, forKey: KEY_WEEKLY_AMOUNT) 

    print("Saved data.") 
} 

func loadTheDatas() { 
    if let decodedNSDataBlob = defaults.objectForKey(KEY_ARRAY_OF_PURCHASES) as? NSData { 
     if let unarchivedArray = NSKeyedUnarchiver.unarchiveObjectWithData(decodedNSDataBlob) as? NSArray { 

      self.arrayOfUserPurchases = NSMutableArray.init(array: unarchivedArray) 
     } 
    } else { 

     // THIS ALWAYS HAPPENS. // 

     print("No Purchases yet! Initializing with blank array.") 
     arrayOfUserPurchases = NSMutableArray() 
     return 
    } 

    let savedWeeklyAmount = defaults.integerForKey(KEY_WEEKLY_AMOUNT) 
    self.weeklyAmount = savedWeeklyAmount 
    print("Loaded saved weekly amount: \(savedWeeklyAmount).") 

} 

Und der Kaufklasse:

class Purchase : NSObject, NSCoding { 

let KEY_PURCHASE_AMOUNT = "PURCHASE_AMOUNT" 
let KEY_PURCHASE_CATEGORY = "PURCHASE_CATEGORY" 
let KEY_PURCHASE_TIME = "PURCHASE_TIME" 
let KEY_PURCHASE_DATE = "PURCHASE_DATE" 

var amount:Int = 0 
var time:String = "" 
var date:String = "" 
var category:Int = 0 
var valid:Bool = false 

init(amount:Int, time:String, date:String, category:Int) { 
    self.amount = amount 
    self.time = time 
    self.date = date 
    self.category = category 
    self.valid = true 
} 

override init() { 
    self.valid = false 
} 

// MARK: NSCoding 
required convenience init?(coder aDecoder: NSCoder) { 

    guard let amount = aDecoder.decodeObjectForKey("amount") as? Int 
     else { 
      self.init() 
      return 
     } 
    guard let time = aDecoder.decodeObjectForKey("time") as? String 
     else { 
      self.init() 
      return 
    } 
    guard let date = aDecoder.decodeObjectForKey("date") as? String 
     else { 
      self.init() 
      return 
    } 
    guard let category = aDecoder.decodeObjectForKey("category") as? Int 
     else { 
      self.init() 
      return 
    } 
    guard let valid = aDecoder.decodeObjectForKey("valid") as? Bool 
     else { 
      self.init() 
      return 
    } 

    self.init(amount: amount, time: time, date: date, category: category) 
} 



func encodeWithCoder(aCoder: NSCoder) { 
    aCoder.encodeInt(Int32(self.amount), forKey: "amount") 
    aCoder.encodeObject(self.time, forKey: "time") 
    aCoder.encodeObject(self.date, forKey: "date") 
    aCoder.encodeInt(Int32(self.category), forKey: "category") 
    aCoder.encodeBool(self.valid, forKey: "valid") 
} 

}

Antwort

0

Ihre Purchase-Klasse Bedürfnisse folgende Verbesserungen

Statt eine guard Anweisung if let wie

if let amount = aDecoder.decodeObjectForKey("amount") as? Int 
{ 
     self.amount = amount 
} 
der Verwendung 0

über Ihre init Anrufe innerhalb initWithCoder Forget, Es ist bereits Ihr Objekt initialisiert wird, so brauchen Sie nicht wieder an init

auch versuchen, Ihre Daten zu speichern mit encodeObject wie

aCoder.encodeObject(amount, forKey: "amount") 
Verwandte Themen