7

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

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

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

错误

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

4

2 回答 2

20

唷,我得到了它的工作:

这是保存with对象的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")
      }
 }
于 2017-07-12T13:41:39.947 回答
0

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

(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
    }
}
于 2021-12-28T11:44:28.233 回答