【问题标题】:Plist encoding and decoding back to Dictionary [String:Decodable]Plist 编码和解码返回字典 [String:Decodable]
【发布时间】:2020-09-28 10:15:13
【问题描述】:

我希望能够将 [String:Codable] 类型的字典保存到 plist 并恢复原样。我试过了,但它会抛出错误:

  let dictionary:[String:Any] = ["point":CGPoint(1,1), "value": 10, "key" : "testKey"] 

   do { 
        let url = FileManager.default.temporaryDirectory.appendingPathComponent("test.plist")
        try savePropertyList(dictionary, toURL: url)
        buildFromPlist(url)
      } catch {
        print(error)
    }
  


    private func savePropertyList(_ plist: Any, toURL url:URL) throws
   {
    let plistData = try PropertyListSerialization.data(fromPropertyList: plist, format: .xml, options: 0)
    try plistData.write(to: url)
   }

  private func buildFromPlist(_ url:URL)
  {
       do {
          let data = try Data(contentsOf: url)
          let decoder = PropertyListDecoder()
          let dictionary = try decoder.decode([String:Decodable], from: data)
          NSLog("\(dictionary)")
      } catch {
           NSLog("Error decoding \(error)")
      }
   
    
   }

但我在解码功能中遇到构建错误:

  Value of protocol type 'Decodable' cannot conform to 'Decodable'; only struct/enum/class types can conform to protocols

我想知道我是如何读回我保存到 plist 文件中的字典的?

编辑:即使 savePropertyList 在运行时使用 CGPoint 和 CGAffineTransform 等对象也会失败并出现错误 -

 "Property list invalid for format: 100 (property lists cannot contain objects of type 'CFType')" UserInfo={NSDebugDescription=Property list invalid for format: 100 (property lists cannot contain objects of type 'CFType')}

我想知道如何将 Codable 对象写入 plist 并恢复?

【问题讨论】:

    标签: ios swift plist codable


    【解决方案1】:

    这不起作用,因为decoder.decode 行中的类型必须 是具体类型。并且 [String:Decodable] 没有尾随 .self 将引发另一个错误。

    Codable 协议的目标是序列化自定义结构或类,从而使您的字典成为结构

    struct MyType : Codable {
        let point : CGPoint
        let value : Int
        let key : String
    }
    

    并对其进行编码。在解码部分写

    let item = try decoder.decode(MyType.self, from: data)
    

    【讨论】:

    • 好的,我现在明白了,即使保存到属性列表也会失败,并出现符合 Codable/Decodable 协议的对象的错误。但是我的意思是我不能使用固定的结构 MyType。原因,MyType 将来可能会改变。如果我以 plist 格式保存项目并始终解码为 MyType,那么它在某些时候可能无法向后兼容。我只想写入 plist 并读取并将其解码回字典。
    • 如果类型符合Codable,它们确实可以编码到属性列表。当然你必须使用PropertyListEncoder。如果无法使用自定义结构(我怀疑),您必须使用传统的 PropertyListSerialization 并将不兼容的类型转换为 Property List 支持的类型。
    • 当我尝试使用 PropertyListEncode().encode(plist) 时,它给了我构建时间错误,其中 plist 是 [String:Codable]
    • 您只能对符合Encodable 的具体类型进行编码,但不能对协议本身进行编码。
    • 嗯,那么在可能有多个 XML 版本的情况下,编写和解析 XML 的正确解决方案是什么?也就是说,未来可能会有MyType1、MyType2。代码需要正确检测 XML 的版本,然后反序列化为适当的类型。
    猜你喜欢
    • 2019-05-04
    • 2021-08-08
    • 1970-01-01
    • 2021-09-30
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 2012-11-12
    • 2016-05-07
    相关资源
    最近更新 更多