简体   繁体   English

使用JSON数据检索到Swift数据类型

[英]Working with JSON data retrieving into Swift data types

I'm trying to get data from a URL. 我正在尝试从URL获取数据。 It was successful. 成功了 I can download and convert to a dictionary[String : Any ] but response is in nested loops. 我可以下载并转换为dictionary[String : Any ],但响应处于嵌套循环中。 I don't to how to retrieve. 我不怎么找。 Can someone suggest how to get text and value in the response? 有人可以建议如何在回应中获得文字和价值吗?

func getDataFromUrl() {
  let url = URL(string: "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&departure_time=1408046331&origins=37.407585,-122.145287&destinations=37.482890,-122.150235")
  let request = NSMutableURLRequest(url: url!)
  let session = URLSession.shared
  request.httpMethod = "GET"
  let dataTask = session.dataTask(with: request as URLRequest, completionHandler: {(data, response, error) in
    do {
      let jsonData = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String: Any]
      let destinationAddress  = jsonData!["destination_addresses"]
      print("Destination address \(String(describing: destinationAddress!))")
      let origin_addresses  = jsonData!["origin_addresses"]
      print("Origin_addresses \(String(describing: origin_addresses!))")
      let rows  = jsonData!["rows"]
      print("Rows  \(String(describing: rows!))")
      // Here I want to print text and value.

    } catch {
      // handle error
    }
  })
  dataTask.resume()
}

The above answers work, but in my opinion the more swiftier approach is to use Codable . 上面的答案有效,但我认为使用Codable

class MyResponseType:Codable {
    let destination_addresses:String
    let rows:[MyCustomRowData]
}

class MyCustomRowData:Codable {
    let elements:[MyCustomElementsData]
}

class MyCustomElementsData:Codable {
    // properties here
}

Doing this, parsing the json is done like this: 这样做,解析json是这样完成的:

let response = try? JSONDecoder().decode(MyResponseType.self, from: data)

Where the data variable is just the retrieved Data object from the request. 其中data变量只是从请求中检索到的Data对象。

Initially you have to set up some boilerplate code to replicate your expected data format, but working with it is really worth it (and it makes it highly testable). 最初,您必须设置一些样板代码来复制所需的数据格式,但是使用它确实值得(并且使其具有很高的可测试性)。

When the decode succeeds you have a perfectly typed object, it can also have optionals. 解码成功后,您将拥有一个类型完美的对象,它也可以具有可选的对象。 It just wont decode if fields are missing or of the wrong type (which is a good thing). 如果字段丢失或类型错误(这是一件好事),它将不会解码。

Here is the way you can parse text and Value from response: 这是解析响应中的textValue的方法:

do{

            if let jsonData = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String: Any] {

                if let destinationAddress = jsonData["destination_addresses"] as? [String] {
                    print(destinationAddress) //["1 Hacker Way, Menlo Park, CA 94025, USA"]
                }

                if let origin_addresses = jsonData["origin_addresses"] as? [String] {
                    print(origin_addresses) //["3251 Hillview Ave, Palo Alto, CA 94304, USA"]
                }

                if let rows = jsonData["rows"] as? [[String: AnyObject]] {
                    if rows.indices.contains(0) {
                        if let elements = rows[0]["elements"] as? [[String: AnyObject]] {
                            for element in elements {
                                if let duration = element["duration"] as? [String: AnyObject] {
                                    let text = duration["text"] as? String ?? ""
                                    print(text) //17 mins
                                    let value = duration["value"] as? Int ?? 0
                                    print(value) //1010
                                }

                                if let distance = element["distance"] as? [String: AnyObject] {
                                    let text = distance["text"] as? String ?? ""
                                    print(text) //7.2 mi
                                    let value = distance["value"] as? Int ?? 0
                                    print(value) //11555
                                }
                            }
                        }
                    }

                }
            }

        }catch{ //error handle

        }

Use this code: 使用此代码:

  let rows = jsonData["rows"] as! Array
  let element = rows[0] as! Dictionary
  let elementArray = element.value(forKey: "elements")
  let distance = elementArray[0].value(forKey: "distance")
  let text = distance.value(forKey: "text")
  print(text)
  let value = distance.value(forKey: "value")
  print(value)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM