如何在Swift 4中解码通用JSON响应?

时间:2018-01-31 23:48:12

标签: json swift

我正在使用Swift 4构建一个使用JSON-RPC API的应用程序。答案都具有相同的一般格式:

{
    "jsonrpc": "2.0",
    "result" : { "data_type" : [ ...a bunch of instances of data_type... ] }
    "id": 1
}

其中data_typepaymentschannelspeers等,具体取决于查询。

我对每种数据类型都有Decodable struct个定义,但我不知道如何处理主要响应。

我真的不关心jsonrpcid字段,我只是对result的内容感兴趣。

我试过了:

struct LightningRPCResponse: Decodable {
    let id: Int
    let result: String
    let json_rpc: String
}

但是我得到了错误:

  

预计会解码String而不是找到字典

所以我试过了:

struct LightningRPCResponse: Decodable {
    let id: Int
    let result: Dictionary
    let json_rpc: String
}

但是我得到了错误:

  

参考泛型类型'字典'需要< ...>

中的参数

我尝试做的是什么,或者我是否需要创建单独的响应解码器以对应每个RPC请求?

或者......我应该使用字符串操作来删除多余的数据吗?

2 个答案:

答案 0 :(得分:1)

你可以制作两个结构:

struct generalStruct:Codable {
    let jsonrpc:String
    let id:Int
    let result:[resultsStruct]
}

struct resultsStruct{
     //assuming that you have strings in here, cause you didn't specify that. And it's considered as a Dictionary like: "data_tupe":"string_value" or if you have an array also here than just make another struct or just make data_type:[String]
    let data_type:String
}

使用该结构,您现在可以解码。例如:

 let json = try decoder.decode(generalStruct.self, from: response.data!)
 //here you can get access to each element of your 'data_type'
 for obj in json.result{
  for data in obj.data_type {
      //you have every element from dict access here if its more objects inside every 'data_type'
   }
 }

答案 1 :(得分:-1)

如果密钥result的值为Dictionary且密钥类型为String,值类型为[Int](或任何其他类型),那么您可以执行此操作:

import Foundation

let text = """
{
  "jsonrpc": "2.0",
  "result" : { "data_type" : [0,1,2] },
  "id": 1
}
"""

struct LightningRPCResponse: Decodable {
  // Only the field you're interested in
  let result: [String: [Int]]
}

if let data = text.data(using: .utf8),
  let result = try? JSONDecoder().decode(LightningRPCResponse.self, from: data) {
  print(result)
}

// LightningRPCResponse(result: ["data_type": [0, 1, 2]])