【问题标题】:Use Swift Decoder to pull attributes from JSON array使用 Swift 解码器从 JSON 数组中提取属性
【发布时间】:2018-08-09 14:40:09
【问题描述】:

我有一个使用此调用创建的 JSON 数组:

guard let json = (try? JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [Any] else {
    print("This is not JSON!!!")
    return
}

我正在尝试从数组中的 JSON 对象中获取元素以使用以下代码显示它们:

struct sWidget: Codable{
    var createdBy: String
    var createdDate: Date
    var status: String
    var widgetNumber: String
    var updatedBy: String
    var updatedDate: Date
}


do {
    let decoder = JSONDecoder()
    for (index, value) in json.enumerated() {
        let currentWidget = try decoder.decode(sWidget.self, from: json[index] as! Data)
        let currentNum = currentWidget.widgetNumber
            //print(currentNum)
        widgetNums.append(currentNum)
    }
}
catch {
    print("decoding error")
}

代码可以编译,但是当我运行它时,输出中出现此错误:

无法将“__NSDictionaryM”(0x1063c34f8) 类型的值转换为 'NSData' (0x1063c1090)。 2018-08-09 09:41:02.666713-0500 TruckMeterLogScanner[14259:1223764] 无法转换类型的值 '__NSDictionaryM' (0x1063c34f8) 到 'NSData' (0x1063c1090)。

我仍在调查,但任何提示都会有所帮助。

【问题讨论】:

  • 这很正常,因为 json 已经是 Dictionary/Array/String/Int 的数组,已经序列化,所以它里面不会有 Data 对象,所以 json[index] 不是(NS)Data 对象,所以 json[index] as! Data 会崩溃。如果您只是对获取数字感兴趣,请在let widgets = jsonDecoder.decode([sWidget].self, data: content) 之后发送,执行 widgetNums.append(contentsOf: widgets.map{$0.widgetNumber}`。

标签: json swift decoder jsondecoder swift-structs


【解决方案1】:

您是否尝试过像上面提到的那样获取对象?因为我看到你正在使用 Codable。实际上,获取非常简单。

let yourObjectArray = JSONDecoder().decode([sWidget].self, data: json as! Data)

这条线可能有问题,但你可以用一行来获取它们。

【讨论】:

  • 我尝试使用此代码,但我收到一条警告,提示从 [Any] 转换为不相关类型“数据”总是失败
  • 让 yourObjectArray = 试试 JSONDecoder().decode([sTruck].self, from: json as!Data)
  • @Jacobi 您在使用 Alamofire 获取数据吗?这是一个使用 Alamofire 获取函数的示例。我希望它会帮助你。 gist.github.com/Cemoo/3ed4f5a3eff11082b064e745d3ef6b35
【解决方案2】:

扩展@Cemal BAYRI 的答案:

JSONDecoder() 抛出,所以请确保给我们try?try(不要忘记do-catchtry

guard let data = content as? Data else {
   return [sWidget]()
}

let jsonDecoder = JSONDecoder()

1。 试试?

let yourObjectArray = try? jsonDecoder.decode([sWidget].self, data: data)

2。 试试

do {
  let yourObjectArray = try jsonDecoder.decode([sWidget].self, data: data)
} catch let error {
}  

注意:您需要注意DataDate 的格式。以下是Date 的示例:

jsonDecoder.dateDecodingStrategy = .iso8601

您也可以查看here

【讨论】:

  • 让 data = json as?数据不是填充数据。这行代码执行后还是nil
  • 这里json 是包含数据的变量的名称。根据您的问题,应该是content
  • 内容已经是数据类型。我是否将序列化调用替换为解码调用?
  • 是的。解码器取代了序列化以及将 json 转换为模型所需的所有其他步骤
猜你喜欢
  • 2018-05-26
  • 2021-06-13
  • 2022-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多