简体   繁体   English

无法检索自定义Swift对象的已保存数组

[英]Unable to retrieve saved array of custom Swift objects

I'm creating a quick app that tracks user purchases in Swift. 我正在创建一个快速的应用程序,用于跟踪Swift中的用户购买情况。 There's a Purchase class, and I'm trying to save an NSMutableArray of these to the user defaults. 有一个Purchase类,我试图将其中的NSMutableArray保存为用户默认值。

When I go to load the data, after first pressing quitting the app to trigger a save, the else is always ran. 当我去加载数据时,首先按下退出应用程序以触发保存后,其他的总是运行。 Retrieving the integer amount (the data for KEY_WEEKLY_AMOUNT) is always successful though. 不过,检索整数值(KEY_WEEKLY_AMOUNT的数据)始终会成功。

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).")

}

And the Purchase class: 和购买类:

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")
} 

} }

Your Purchase class needs following improvements 您的购买班级需要进行以下改进

Instead of using a guard statement use if let like if let喜欢,请使用guard声明,而不要使用guard声明

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

Forget about your init calls inside initWithCoder, It is already initializing your object, so you don't need to init again 忘记initWithCoder内部的init调用,它已经在初始化您的对象,因此您无需再次进行init

Also try to save your data using encodeObject like 也可以尝试使用encodeObject来保存数据,例如

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM