Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何解析Swift 4中包含字典和数组的JSON?_Json_Swift_Xcode_Parsing - Fatal编程技术网

如何解析Swift 4中包含字典和数组的JSON?

如何解析Swift 4中包含字典和数组的JSON?,json,swift,xcode,parsing,Json,Swift,Xcode,Parsing,我需要一些帮助来解析Swift 4中的JSON,我已经知道如何使用像这样的简单JSON: {"numNotif":1,"numTqClose":7,"reply":3} 但现在我必须解析另一个如此巨大的JSON,它有以下结构: 这就是我解析一个简单JSON的方式,但在本例中它不起作用 import UIKit struct closeDtoList: Decodable { let CategoryStr:String } class test: UIViewCOntroller {

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

{"numNotif":1,"numTqClose":7,"reply":3}
但现在我必须解析另一个如此巨大的JSON,它有以下结构:

这就是我解析一个简单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等的值,但我不知道如何做

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


提前谢谢你

您可以创建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
        }
    }
}

您可以创建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
        }
    }
}

您所需要做的就是根据您的结构解析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

            }
         }
      }
   }
}

数据是您从URLSession调用中获得的数据。基本上,您可以将JSON对象强制转换为已知的任何结构。在上面的示例中,我将responseObj解析为一个
字典
,然后从这个字典中检索
closeDtoList
键的值,作为
字典数组
和该数组的第一个元素(字典)我得到
issueStr
键的值,它是一个
字符串

您需要做的就是根据您的结构解析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

            }
         }
      }
   }
}

数据是您从URLSession调用中获得的数据。基本上,您可以将JSON对象强制转换为已知的任何结构。在上面的示例中,我将responseObj解析为一个
字典
,然后从这个字典中检索
closeDtoList
键的值,作为
字典数组
,从该数组的第一个元素(这是一个字典)我得到
issuest
键的值,它是一个
字符串

什么是“issueId”类型是Int还是[Int]?什么是“issueId”类型是Int还是[Int]?对于
issueId
类型,不需要自定义
init(来自解码器:解码器)
。默认情况下,可选属性是可解码的。添加此属性只是为了澄清,因为在给定的JSONTANK中,IssueId参数类型未知,请耐心等待!但阿亚兹蒙的回答对我有更好的帮助。就IssueId而言,我已经检查了整个JSON,因为对于某些字段,它只是一个Int值数组,不需要为
IssueId
类型自定义
init(来自解码器:解码器)
。默认情况下,可选属性是可解码的。添加此属性只是为了澄清,因为在给定的JSONTANK中,IssueId参数类型未知,请耐心等待!但阿亚兹蒙的回答对我有更好的帮助。就IssueId而言,我已经检查了整个JSON,因为对于某些字段它根本不存在,它是一个Int值数组。非常感谢!!这已经奏效了,很容易理解:)很高兴听到它!:)非常感谢你!!这已经奏效了,很容易理解:)很高兴听到它!:)