如何在Swift 4中解析具有字典和数组的JSON?

时间:2018-10-17 11:51:29

标签: json swift xcode parsing

我需要在Swift 4中解析JSON的帮助,我已经知道如何使用像这样的简单JSON来做到这一点:

{"numNotif":1,"numTqClose":7,"reply":3}

但是现在我必须解析另一个巨大的JSON,它具有以下结构:https://textuploader.com/dnx8f

这就是我解析简单JSON的方式,但是在这种情况下它不起作用

import UIKit
struct closeDtoList: Decodable {
  let CategoryStr:String
}
class test: UIViewCOntroller {
  super.viewDidLoad() {
    let urlJSON = "http://www.example.net/site/gitAll"
    guard let url = URL(string: urlJSON) else {return}
    URLSession.shared.dataTask(with: url) { (data, response, error) in
      guard let data = data else {return}
      guard error == nil else {return}
      do {
        let closeDto = try JSONDecoder().decode(closeDtoList.self, from: data)
        print(closeDto.CategoryStr)
      } catch let error {
        print(error)
  }.resume()
}

好吧,所以我想使用相同的代码或相似的代码来解析一个在值之前具有字典“ {}”和数组“ []”的JSON,所以实际上我想获取该值有关issueId,CategoryStr等的信息,但我对该操作方法一无所知。

另外,我需要将这些值保存在数组中(每个字段中的每个值),有可能吗?

提前谢谢!

2 个答案:

答案 0 :(得分:1)

您可以创建ToDoList结构,其中包含closeDtoList,openDtoList结构作为参数。结构如下所示。从json尚不清楚IssueId类型,请将其更改为符合要求。

import Foundation

struct ToDoList: Decodable {
    let closeDtoList, openDtoList: [DtoList]
}

struct DtoList: Decodable {
    let issueID: IssueID
    let issueStr, categoryStr: String
    let hasImg: Bool
    let tasksID: IssueID
    let userAssign, userStart: Int

    enum CodingKeys: String, CodingKey {
        case issueID = "issueId"
        case issueStr
        case categoryStr = "CategoryStr"
        case hasImg
        case tasksID = "tasksId"
        case userAssign, userStart
    }
}

struct IssueID: Decodable {

    let id: Int?

    enum CondingKeys: String, CodingKey {
        case id = "id" //replace this with correct id value
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CondingKeys.self)
        if let issueId = try? container.decodeIfPresent(Int.self, forKey: .id) {
            self.id = issueId
        } else {
            self.id = nil
        }
    }
}

答案 1 :(得分:1)

您需要做的就是根据您的结构解析JSON。例如:

if let responseObj = try? JSONSerialization.jsonObject(with: data) {
   if let responseData = responseObj as? [String: Any] { // Parse dictionary
      if let closeDtoList = responseData["closeDtoList"] as? [[String: Any]] {// Parse an array containing dictionaries
         if closeDtoList.count > 0 {
            // You should use a loop here but I'm just doing this way to show an example
            if let issueStr = closeDtoList[0]["issueStr"] as? String { // Parse a string from dictionary

            }
         }
      }
   }
}

data是您从URLSession调用中获得的。基本上,您将JSON对象转换为已知的任何结构。在上面的示例中,我将responseObj解析为Dictionary,然后从该字典中将closeDtoList的键值恢复为Array of Dictionaries,并从该数组的第一个元素(字典)中得到{{ 1}}键的值为issueStr