【问题标题】:Swift: Parsing a JSON file where you don't know the key valuesSwift:解析不知道键值的 JSON 文件
【发布时间】:2020-08-09 03:48:43
【问题描述】:

我正在构建一个使用 json 查询 wikidata 的应用程序。到目前为止它有效,但我遇到的问题是我从 wikidata 获得的响应不是实际数据,而是标识符。然后,要转换该标识符,我需要将其发送到另一个 url 并接收另一个 json 响应,但我遇到的问题是,在我收到第一个 json 响应之前,我不知道键值。所以,假设我的密钥是 Q1169621。当我通过 api 运行它时,我得到以下响应:

我正在使用 codable 和 JSONDecoder,但我不知道如何告诉解码器实体中键的值是 Q1169621 以获得我想要的值(“Jim Lauderdale”)......我的一些代码在下面,我有结构来定义响应的数据,但是如何将结构中的键值替换为从前一个解码的 json 中定义的键值?

struct InfoFromWikiConverted: Codable {
    
    let entities: Locator //this is the value I need to set before parsing the json
    
}

struct Locator: Codable {
    
    let labels: Labels //how do I link this to the struct above?
}

struct Labels: Codable {
    
    let en: EN
}

struct EN: Codable {
    
    let value: String
}

【问题讨论】:

  • 解码字典:let entities: [String:Locator] 或编写自定义初始化程序。

标签: json swift wikipedia codable wikidata-api


【解决方案1】:

最简单的方法是将entities解码为[String: Locator]

struct InfoFromWikiConverted: Decodable {
   let entities: [String: Locator]
}

当然,如果您希望您的模型只是一个 Locator(这意味着可能会忽略 entities 下的多个键),那么您需要手动对其进行解码。

您需要创建一个类型来表示任何字符串编码键并实现init(from:)

struct InfoFromWikiConverted: Decodable {
   let entities: Locator
   
   struct CodingKeys: CodingKey {
      var stringValue: String
      var intValue: Int? = nil
        
      init(stringValue: String) { self.stringValue = stringValue }
      init?(intValue: Int) { return nil }
   }

   init(from decoder: Decoder) throws {
      let container = try decoder.container(keyedBy: CodingKeys.self)

      // get the first key (ignore the rest), and throw if there are none
      guard let key = container.allKeys.first else {
         throw DecodingError.dataCorrupted(
            .init(codingPath: container.codingPath, 
                  debugDescription: "Expected a non-empty object"))
      }

      let entities = try container.decode(Locator.self, forKey: key)
   }
}

请注意,由于您没有保留 ID,因此无法将其编码回相同的形式,因此我只符合 Decodable 而不是 Codable

【讨论】:

    猜你喜欢
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 2020-06-22
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    相关资源
    最近更新 更多