【问题标题】:How to save an Array with Objects to UserDefaults如何将包含对象的数组保存到 UserDefaults
【发布时间】:2017-12-16 21:40:53
【问题描述】:

我的对象符合新的 Swift 4 Codeable 协议。如何将这些对象的数组保存在UserDefaults中?

struct MyObject: Codeable {
    var name: String
    var something: [String]
}

myObjectsArray = [MyObject]() // filled with objects
UserDefaults.standard.set(myObjectsArray, forKey: "user_filters")

错误

由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'尝试插入非属性 列表对象

【问题讨论】:

    标签: swift4 userdefaults


    【解决方案1】:

    哇,我搞定了:

    这里是 Swift 4 语法来保存 ArrayCodeable 对象:

    我的解决方案是将其编码为 JSON 对象并保存:

    static var getAllObjects: [MyObject] {
          let defaultObject = MyObject(name: "My Object Name")
          if let objects = UserDefaults.standard.value(forKey: "user_objects") as? Data {
             let decoder = JSONDecoder()
             if let objectsDecoded = try? decoder.decode(Array.self, from: objects) as [MyObject] {
                return objectsDecoded
             } else {
                return [defaultObject]
             }
          } else {
             return [defaultObject]
          }
       }
    
     static func saveAllObjects(allObjects: [MyObject]) {
          let encoder = JSONEncoder()
          if let encoded = try? encoder.encode(allObjects){
             UserDefaults.standard.set(encoded, forKey: "user_objects")
          }
     }
    

    【讨论】:

    • 这是一个不错的解决方案 - 我使用的是属性列表编码器。标记自己是正确的!
    • KeyedArchiver 怎么样?
    【解决方案2】:

    您可以使用更通用的方法,使用具有特定类型的数组:

    (myObject = 任何您喜欢的自定义可编码对象)

    (myKey = 能够检索/设置特定数组的字符串常量键)

    //set
    setObject(myArray, forKey: mykey)
    
    //get
    let myArray = getObject(forKey: mykey, castTo: Array<myObject>.self)
    

    还有泛型函数,适用于任何类型:

    func setObject<Object>(_ object: Object, forKey: String) where Object: Encodable
    {
        let encoder = JSONEncoder()
        do {
            let data = try encoder.encode(object)
            set(data, forKey: forKey)
            synchronize()
        } catch let encodeErr {
            print("Failed to encode object:", encodeErr)
        }
    }
        
    func getObject<Object>(forKey: String, castTo type: Object.Type) -> Object? where Object: Decodable
    {
        guard let data = data(forKey: forKey) else { return nil }
        let decoder = JSONDecoder()
        do {
            let object = try decoder.decode(type, from: data)
            return object
        } catch let decodeError{
            print("Failed to decode object:" , decodeError)
            return nil
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-18
      • 2021-04-08
      • 1970-01-01
      相关资源
      最近更新 更多