如何解析带有数组的JSON和更多JSON?

时间:2018-05-16 15:24:24

标签: ios json swift parsing codable

我最近开始使用swift。我需要解码下面的json。

JSON内部还有两个JSON,第一个JSON(验证)无关紧要。第二个(结果)内部有一个JSON数组(serviceCenter)。我需要每个服务中心的信息。我尝试使用servicecenter作为可解析的类来获取servicenter对象,但由于JSON没有正确的格式,我无法做到。

[
  {
    "validation": {
      "bValid": true,
      "sDescription": "Access true."
    }
  },
  {
    "result": {
      "serviceCenter": [
        {
          "model": "Vanquish",
          "color": "Purple",
          "make": "Aston Martin",
          "sTag": "3666",
          "sVin": "6JDO2345",
          "sMiles": "3666",
          "bDamage": "1",
          "dDateTime": "04-17-2018 9:38 AM"
        },
        {
          "model": "F360",
          "color": "Red",
          "make": "Ferrari",
          "sTag": "0010",
          "sVin": "6JDO2347",
          "sMiles": "80000",
          "bDamage": "1",
          "dDateTime": "04-17-2018 9:25 AM"
        },
        {
          "model": "Vanquish",
          "color": "Purple",
          "make": "Aston Martin",
          "sTag": "0009",
          "sVin": "6JDO2345",
          "sMiles": "25000",
          "bDamage": "1",
          "dDateTime": "04-17-2018 9:23 AM"
        },
        {
          "model": "Vanquish",
          "color": "Purple",
          "make": "Aston Martin",
          "sTag": "0003",
          "sVin": "6JDO2345",
          "sMiles": "20000",
          "bDamage": "1",
          "dDateTime": "04-12-2018 10:37 AM"
        }
      ]
    }
  }
]

我尝试了很多,但我无法做到。

这是我的代码,请有人帮助我

do {
    let parseoDatos = try JSONSerialization.jsonObject(with: data!) as! [AnyObject]
    let h = type(of: parseoDatos )
    print("'\(parseoDatos)' of type '\(h)'")
    let contenido = parseoDatos[1]["result"]

    if let services = contenido!! as? Dictionary<String, Array<Any>> {               
        for (_,serviceArray) in services {
            for sc in serviceArray{
                let h = type(of: sc )
                print("'\(sc)' of type '\(h)'")                        
            }
        }
    }
} catch {
    print("json processing failed")
}

打印sc的结果是

{
    bDamage = 1;
    color = Purple;
    dDateTime = "04-17-2018 9:38 AM";
    make = "Aston Martin";
    model = Vanquish;
    sMiles = 3666;
    sTag = 3666;
    sVin = 6JDO2345;
}' of type '__NSDictionaryI'

4 个答案:

答案 0 :(得分:2)

试试这段代码

enum ParsingError: Error {
    case wrongFormat(String)
}

do {
    let jsonObject = try JSONSerialization.jsonObject(with: data!)
    guard let array = jsonObject as? [Any] else {
        throw ParsingError.wrongFormat("wrong root object")
    }
    guard array.count == 2 else {
        throw ParsingError.wrongFormat("array count != 2")
    }
    guard let dict = array[1] as? [String: Any] else {
        throw ParsingError.wrongFormat("can't parse dict from array")
    }
    guard let serviceCenters = (dict["result"] as? [String: Any])?["serviceCenter"] else {
        throw ParsingError.wrongFormat("can't parse serviceCenters")
    }
    guard let serviceCentersArray = serviceCenters as? [[String : Any]] else {
        throw ParsingError.wrongFormat("serviceCenters is not an array")
    }

    print("\(type(of: serviceCentersArray))\n", serviceCentersArray)

} catch {
    print("json processing failed: \(error)")
}

答案 1 :(得分:2)

您可以使用Codable

初始响应包含 InitialElement 数组,而InitialElement是包含validationresult的结构,结果可能

请勿忘记在url

添加您的网址
URLSession.shared.dataTask(with: url!) { (data, response, error) in

                     if  let initial =  try? JSONDecoder().decode([InitialElement].self, from: data){

                         // inital now have array of InitialElement and InitialElement is is struct with validation , result  , result may be nil


                        print(initial)
                        }
                    }.resume()

使用此数据模型:

import Foundation

struct InitialElement: Codable {
    let validation: Validation?
    let result: ResultData?
}

struct ResultData: Codable {
    let serviceCenter: [ServiceCenter]
}

struct ServiceCenter: Codable {
    let model, color, make, sTag: String
    let sVin, sMiles, bDamage, dDateTime: String
}

struct Validation: Codable {
    let bValid: Bool
    let sDescription: String
}


extension InitialElement {
    init(data: Data) throws {
        self = try JSONDecoder().decode(InitialElement.self, from: data)
    }
}

答案 2 :(得分:0)

感谢所有人的回答,这是我的第一个问题,我感觉很棒所有的帮助。最后我可以解决问题。也许不是最好的方法,但这里是代码:

let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
        if error != nil{
            print("error=\(String(describing: error))")
            return
        }
        do {

            let parseoDatos = try JSONSerialization.jsonObject(with: data!) as! [AnyObject]
            let h = type(of: parseoDatos )
            print("'\(parseoDatos)' of type '\(h)'")
            let contenido = parseoDatos[1]["result"]


            if let services = contenido!! as? Dictionary<String, Array<Any>> {
                for (_,serviceArray) in services {
                    for sc in serviceArray{
                        let h = type(of: sc )
                        print("'\(sc)' of type '\(h)'")
                        let valid = JSONSerialization.isValidJSONObject(sc) // true
                        print(valid)
                        do {
                            let jsonData = try JSONSerialization.data(withJSONObject: sc, options: .prettyPrinted)
                            let serviceDecoded = try JSONSerialization.jsonObject(with: jsonData, options: [])
                            if let scJSON = serviceDecoded as? [String:String] {
                                print ("--------------------------")
                                print("'\(scJSON)' of type '\(type(of: scJSON))'")
                                print ("--------------------------")


                            }
                        } catch {
                            print(error.localizedDescription)
                        }

我想稍后我会尝试按照建议使用Codable,但是现在代码工作正常。再次感谢!

答案 3 :(得分:-2)

//try this it is working

let arrayMain=try?JSONSerialization.jsonObject(with:jsonData!,options:.mutableLeaves) as! Array<Any>


//print(arrayMain!)

if let firstDictionart=arrayMain![0] as? [String: Any] {
    if let insideFirstDict = firstDictionart["validation"] as? [String: Any]{
       print(insideFirstDict["bValid"]!)
         print( insideFirstDict["sDescription"]!)

    }

}
if let resultDictionary=arrayMain![1] as? [String: Any] {
    if let serviceDictionary = resultDictionary["result"] as? [String: Any] {
        for array in serviceDictionary["serviceCenter"] as! Array<Any>{
            if let infoDicti=array as? [String: Any]  {
                print( infoDicti["color"]!)
                print( infoDicti["make"]!)
                print(  infoDicti["color"]!)
                print( infoDicti["sTag"]!)
                print( infoDicti["sVin"]!)
                print( infoDicti["sMiles"]!)
                print( infoDicti["sVin"]!)
                print( infoDicti["model"]!)
                print( infoDicti["bDamage"]!)
                print( infoDicti["dDateTime"]!)         
            } 
        }
      }

    }