代码之家  ›  专栏  ›  技术社区  ›  PaFi

顶层Bool编码为数字属性列表片段。PropertyListEncoder属性

  •  3
  • PaFi  · 技术社区  · 7 年前

    extension UserDefaults {
        func saveUserDefaults<T: Codable>(withKey key: String, myType: T) throws{
            do {
                let data = try PropertyListEncoder().encode(myType)
                UserDefaults.standard.set(data, forKey: key)
                print("Saved for Key:", key)
            } catch let error {
    
                print("Save Failed")
                throw error
            }
        }
    

    我这样称呼它:

    try! UserDefaults().saveUserDefaults(withKey: "String", myType: false)
    

    这就是我得到的错误。我知道还有另一种保存布尔值的方法,但我想知道为什么它不能这样工作?

    Swift.EncodingError.invalidValue(false, Swift.EncodingError.Context(编码路径:[],调试描述: “顶级Bool编码为数字属性列表片段。”, 基线误差:零)

    谢谢

    1 回复  |  直到 7 年前
        1
  •  1
  •   Martin R    7 年前

    A. PropertyListEncoder 编码到属性列表,这始终是 数组或字典,比较 PropertyListSerialization

    因此

    let data = try PropertyListEncoder().encode(myType)
    

    失败,如果 myType 是一个 Bool (或任何不是数组的东西 或者一本字典)。

    NSData , NSString , NSArray , NSDictionary NSDate NSNumber

        2
  •  1
  •   Vladimir    7 年前

    正如@Martin所说,PropertyListEncoder只支持顶层的属性列表,而不支持像NSNumber这样的单个属性列表片段。 一个非常简单(虽然不是很优雅)的解决方法是将任何对象包装到数组中:

    let data = try PropertyListEncoder().encode([myType])
    UserDefaults.standard.set(data, forKey: key)
    

    并将其解码为:

    let arr = try  PropertyListDecoder().decode([T].self, from: data)
    return arr.first
    

    https://www.marisibrothers.com/2018/07/workaround-for-serializing-codable-fragments.html

        3
  •  0
  •   deniz    5 年前

    不需要对布尔值进行编码就可以保存为UserDefaults。您可以通过调用

        let myValue: Bool = false
        UserDefaults.standard.set(myValue, forKey: "key")
    

    参见Apple文档: UserDefaults.set(_:forKey:)

    我看到您有一个函数,它采用可编码类型,对其进行编码,然后将其保存为UserDefaults。正如martinr所指出的,您必须修改该函数,并检查传递的对象是否可以直接保存为UserDefaults而无需编码。