Swift Codable 期望解码 Dictionary<String, Any> 但找到了一个字符串/数据

Posted

技术标签:

【中文标题】Swift Codable 期望解码 Dictionary<String, Any> 但找到了一个字符串/数据【英文标题】:Swift Codable expected to decode Dictionary<String, Any>but found a string/data instead 【发布时间】:2018-04-11 08:09:41 【问题描述】:

我一直在使用Codable 协议

这是我的JSON 文件:

      
   "Adress":[  

   ],
   "Object":[  
        
         "next-date":"2017-10-30T11:00:00Z",
         "text-sample":"Some text",
         "image-path":[  
            "photo1.png",
            "photo2.png"
         ],
         "email":"john.doe@test.com",
         "id":"27"
      ,
        
         "next-date":"2017-10-30T09:00:00Z",
         "text-sample":"Test Test",
         "image-path":[  
            "image1.png"
         ],
         "email":"name.lastename@doe.com",
         "id":"28"
      
   ]

我只需要关注 Object 数组,“image-path”数组可以包含 0、1 或 2 个字符串。

这是我的实现:

struct Result: Codable 
    let Object: [MyObject]


struct MyObject: Codable 

    let date: String
    let text: String
    let image: [String]
    let email: String
    let id: String

    enum CodingKeys: String, CodingKey 
        case date = "next-date"
        case text = "text-sample"
        case image = "image-path"
        case email = "email"
        case id = "id"
    

    init() 
        self.date = ""
        self.text = ""
        self.image = []
        self.email = ""
        self.id = ""
    

在以这种方式请求和获取 JSON 数据后,我从我的服务类中调用它:

if let data = response.data 
                let decoder = JSONDecoder()
                let result = try! decoder.decode(Result, from: data)
                dump(result.Object)
            

除了 image 属性的 [String] 之外,一切正常

但它无法编译,或者我收到“Expected to decode...”错误。

我应该如何处理 nil/no data 场景?

【问题讨论】:

基本上代码(第一个实现)应该可以工作,但 JSON 无效。如果您一直使用解码器,则根本不需要init 方法。 【参考方案1】:

我对你的MyObject struct做了一个小改动,即,

1.将所有properties标记为optionals

2.删除init()(我觉得这里没有init()的要求。)

3.decoder.decode(...)方法中使用Result.self而不是Result

struct MyObject: Codable

    let date: String?
    let text: String?
    let image: [String]?
    let email: String?
    let id: String?

    enum CodingKeys: String, CodingKey
    
        case date = "next-date"
        case text = "text-sample"
        case image = "image-path"
        case email = "email"
        case id = "id"
    

为了测试上面的内容,我使用了下面的代码,它工作正常。

    let jsonString = """
        "Adress": [],
        "Object": ["next-date": "2017-10-30T11:00:00Z",
        "text-sample": "Some text",
        "image-path": ["photo1.png", "photo2.png"],
        "email": "john.doe@test.com",
        "id": "27",
      "next-date": "2017-10-30T09:00:00Z",
       "text-sample": "Test Test",
       "image-path": ["image1.png"],
       "email": "name.lastename@doe.com",
       "id": "28"
       ]
        
    """
    if let data = jsonString.data(using: .utf8)
    
        let decoder = JSONDecoder()
        let result = try? decoder.decode(Result.self, from: data) //Use Result.self here
        print(result)
    

这是我得到的结果值:

【讨论】:

使用相同的样本我无法使其工作。 “debugDescription:“预期解码 Array,但找到了一个字符串/数据。”,基础错误:nil)):文件 /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.65.2/src /swift/stdlib/public/core/ErrorType.swift,第 181 行“ 你使用了 Result.self 吗? Marked all properties as optionals — 你为什么要这样做? 因为没有确认你会从 API 中获取所有的键值对。与其用空字符串/数组初始化它们,不如将它们设为 nil 更好。这就是我为他们使用 optional 的原因。 @PGDev 绝对正确。永远不要相信后端:-)

以上是关于Swift Codable 期望解码 Dictionary<String, Any> 但找到了一个字符串/数据的主要内容,如果未能解决你的问题,请参考以下文章

使用 Swift 4 的 Codable 进行解码时,是啥阻止了我从 String 到 Int 的转换?

Swift Codable 将空 json 解码为 nil 或空对象

使用 swift Codable 以值作为键来解码 JSON

Swift Codable - 如何编码和解码字符串化的 JSON 值?

Swift4 中的 Codable 和 XMLParser

使用 Codable 解码 JSON,然后填充我的 SwiftUI