如何在默认用户中保存对象列表?

时间:2018-08-12 20:05:04

标签: ios arrays swift list nsuserdefaults

我的对象是:

 struct Order: Codable {
        var item_id:String = ""
        var quantity:Int = 0
        var image:String = ""
        var name:String = ""
        var desc:String = ""
    }

,函数的类别是:

    class func saveOrder(value: [Order]) {
        print(value)
        let placesData = NSKeyedArchiver.archivedData(withRootObject: value)
        UserDefaults.standard.set(placesData, forKey: "orderHistoryArray")
    }

    class func getOrder() -> [Order] {
        if let order = UserDefaults.standard.array(forKey: "orderHistoryArray") {
            return order as! [Order]
        }
        return []
    }

当我尝试使用此功能时:

            SavedData.saveOrder(value: itemsInCart)

它不和我一起工作,有帮助吗?!!!

6 个答案:

答案 0 :(得分:2)

您正在混淆协议CodableNSCoding

1)NSCoding

NSKeyed(Un)Archiver 属于NSCoding。要使用它,您必须声明Order为从NSObject继承的 class ,并采用该协议及其必需的方法

class Order: NSObject, NSCoding {
    var item_id : String // no need to assign default values
    var quantity : Int
    var image : String
    var name : String
    var desc : String

    required init(coder decoder: NSCoder) 
    {
        item_id = decoder.decodeObject(forKey: "item_id") as! String
        quantity = decoder.decodeInteger(forKey: "quantity")
        image = decoder.decodeObject(forKey: "image") as! String
        name = decoder.decodeObject(forKey: "name") as! String
        desc = decoder.decodeObject(forKey: "desc") as! String
    }

    func encode(with coder: NSCoder) 
    { 
        coder.encode(item_id, forKey: "item_id")
        coder.encode(quantity, forKey: "quantity")
        coder.encode(image, forKey: "image")
        coder.encode(name, forKey: "name")
        coder.encode(desc, forKey: "desc")
    }
}

然后您可以加载和保存数据

class func saveOrder(value: [Order]) {
    print(value)
    let placesData = NSKeyedArchiver.archivedData(withRootObject: value)
    UserDefaults.standard.set(placesData, forKey: "orderHistoryArray")
}

class func getOrder() -> [Order] {
    guard let orderData = UserDefaults.standard.data(forKey: "orderHistoryArray"),
          let order = NSKeyedUnarchiver.unarchiveObject(with: orderData) as? [Order] else { return [] }
    return order
}

2)可编码

使用Codable可以保留您的结构。只需采用协议并将编码器创建的Data保存到磁盘

struct Order : Codable {
    var item_id : String
    var quantity : Int
    var image : String
    var name : String
    var desc : String
}

// Both methods `throw` to hand over an en-/decoding error to the caller
class func saveOrder(value: [Order]) throws {
    print(value)
    let placesData = try JSONEncoder().encode(value) else { return }
    UserDefaults.standard.set(placesData, forKey: "orderHistoryArray")
}

class func getOrder() throws -> [Order] {
    guard let orderData = UserDefaults.standard.data(forKey: "orderHistoryArray") else { return [] }
    return try JSONDecoder().decode([Order].self, from: orderData)
}

答案 1 :(得分:0)

如果您实现Codable,请使用

do {
     let data = try JSONEncoder().encode(arr)
     // save data here 

     // to load
     let data = //// get it here 
     let arr = try JSONDecoder().decode([Order].self,data)

   }
   catch {
     print(error)
   }

答案 2 :(得分:0)

要使您的NSKeyedArchiver.archivedData(withRootObject: value)工作,您的Order必须符合Codable协议。只要将这些添加到您的Order结构中,它就可以正常工作。

required public init(coder decoder: NSCoder) {

    item_id = decoder.decodeObject(forKey: "item_id") as? String ?? ""
    quantity = decoder.decodeObject(forKey: "quantity") as? Int ?? 0
    image = decoder.decodeObject(forKey: "image") as? String ?? ""
    name = decoder.decodeObject(forKey: "name") as? String ?? ""
    desc = decoder.decodeObject(forKey: "desc") as? String ?? ""

}

public func encode(with coder: NSCoder) {

    coder.encode(item_id, forKey: "item_id")
    coder.encode(quantity, forKey: "quantity")
    coder.encode(image, forKey: "image")
    coder.encode(name, forKey: "name")
    coder.encode(desc, forKey: "desc")
}

答案 3 :(得分:0)

可编码

您可以使用Codable将阵列保存到UserDefaults或从UserDefaults加载阵列。

保存

这是保存它的方式

class func saveOrders(_ orders: [Order]) {
    guard let data = try? JSONEncoder().encode(orders) else { return }
    UserDefaults.standard.set(data, forKey: "orders")
}

加载

这就是您加载它的方式

class func loadOrders() -> [Order] {
    guard
        let data = UserDefaults.standard.data(forKey: "orders"),
        let orders = try? JSONDecoder().decode([Order].self, from: data)
    else { return [] }
    return orders
}

答案 4 :(得分:0)

您可以仅使用属性列表编码器和属性列表解码器将模型保存为用户默认值。简单:

假设您有一个Order类型的模型,

class func saveOrder(value: [Order]) {
    PropertyListEncoder().encode(value), forKey: "Somekey")
}

class func getOrder() -> [Order]? {
    if let data = UserDefaults.standard.value(forKey: "Somekey") as? Data {
        let orderDetail = try? PropertyListDecoder().decode([Order].self, from: data)
        return orderDetail!
    } else {
        return nil
    }
}

一般示例

假设您使用Json Decoder对某些数据进行解码,如下所示:

let decodedValue = try JSONDecoder().decode(Order.self, from: data)

OR

let decodedValue : Order = Order(a: 1, b: 0) // your order model value type,

//现在您可以轻松地将解码的模型对象保存为用户默认值

do {
      UserDefaults.standard.set(try PropertyListEncoder().encode(decodedValue), forKey: "Some key")
} catch let err {
      print(err)
}

答案 5 :(得分:0)

我使用此类来解决这个问题:

class Order: NSObject, NSCoding {


var item_id:String = ""
var quantity:String = ""
var image:String = ""
var name:String = ""
var desc:String = ""

init(item_id: String ,quantity : String , image : String , name: String, desc: String){
    self.item_id = item_id
    self.quantity = quantity
    self.image = image
    self.name = name
    self.desc = desc
}

func encode(with aCoder: NSCoder) {
    aCoder.encode(item_id, forKey: "item_id")
    aCoder.encode(quantity, forKey: "quantity")
    aCoder.encode(image, forKey: "image")
    aCoder.encode(name, forKey: "name")
    aCoder.encode(desc, forKey: "desc")
}

required init?(coder aDecoder: NSCoder) {
    self.item_id = aDecoder.decodeObject(forKey: "item_id") as! String
    self.quantity = aDecoder.decodeObject(forKey: "quantity") as! String
    self.image = aDecoder.decodeObject(forKey: "image") as! String
    self.name = aDecoder.decodeObject(forKey: "name") as! String
    self.desc = aDecoder.decodeObject(forKey: "desc") as! String
}
}

然后我使用此功能来使用它

class func save(value : Order){
    var orderArray:[Order] = retrive()
    orderArray.append(value)
    let orderArrayAchived = NSKeyedArchiver.archivedData(withRootObject: orderArray)
    UserDefaults.standard.set(orderArrayAchived, forKey: "orderArray")
}

class func saveListOfOrder(value: [Order]) {
    print(value)
    let cartArrayAchived = NSKeyedArchiver.archivedData(withRootObject: value)
    UserDefaults.standard.set(cartArrayAchived, forKey: "orderArray")
}

class func retrive()-> [Order]{
    let orderData = UserDefaults.standard.object(forKey: "orderArray") as? NSData
    if orderData == nil
    {
        return [Order]()
    }
    let orderArray = NSKeyedUnarchiver.unarchiveObject(with: orderData! as Data) as? [Order]
    return orderArray!
}