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

时间:2021-05-08 13:20:44

I'm creating a quick app that tracks user purchases in Swift. There's a Purchase class, and I'm trying to save an NSMutableArray of these to the user defaults.

我正在创建一个快速应用程序,用于跟踪Swift中的用户购买。有一个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")
} 

}

1 个解决方案

#1


0  

Your Purchase class needs following improvements

您的购买类需要以下改进

Instead of using a guard statement use if let like

如果让我喜欢,而不是使用保护声明

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调用,它已经初始化你的对象,所以你不需要再次初始化

Also try to save your data using encodeObject like

还尝试使用encodeObject保存数据

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

#1


0  

Your Purchase class needs following improvements

您的购买类需要以下改进

Instead of using a guard statement use if let like

如果让我喜欢,而不是使用保护声明

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调用,它已经初始化你的对象,所以你不需要再次初始化

Also try to save your data using encodeObject like

还尝试使用encodeObject保存数据

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