首页 > 解决方案 > 快速解析 JSON 数据

问题描述

我正在尝试解析伦敦眼的经度和纬度。我的代码如下

这是我的课:

struct Location: Decodable{
    let location: String
    let lat: Double
    let long: Double

}

这是我的功能

func getData(){
        let url = "URL FOR THE JSON"
        let urlOBJ = URL(string: url)

        URLSession.shared.dataTask(with: urlOBJ!){(data,response,errror) in

            do{
                let locations = try JSONDecoder().decode([Location].self, from: data!)

                for x in locations{
                    print(x.lat)
                }
            }

            catch{
                print("We got an error")
            }

    }.resume()

这是我的 JSON 响应:

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "918",
               "short_name" : "918",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "12th Street",
               "short_name" : "12th St",
               "types" : [ "route" ]
            },
            {
               "long_name" : "New Westminster",
               "short_name" : "New Westminster",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Greater Vancouver",
               "short_name" : "Greater Vancouver",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "British Columbia",
               "short_name" : "BC",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "Canada",
               "short_name" : "CA",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "V3M 6B1",
               "short_name" : "V3M 6B1",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "918 12th St, New Westminster, BC V3M 6B1, Canada",
         "geometry" : {
            "location" : {
               "lat" : 49.2122785,
               "lng" : -122.9368196
            },
            "location_type" : "ROOFTOP",
            "viewport" : {
               "northeast" : {
                  "lat" : 49.21362748029149,
                  "lng" : -122.9354706197085
               },
               "southwest" : {
                  "lat" : 49.21092951970849,
                  "lng" : -122.9381685802915
               }
            }
         },
         "place_id" : "ChIJt0rd0NB3hlQRWKnWCK79k1s",
         "plus_code" : {
            "compound_code" : "6367+W7 New Westminster, British Columbia, Canada",
            "global_code" : "84XV6367+W7"
         },
         "types" : [ "doctor", "establishment", "health", "point_of_interest" ]
      }
   ],
   "status" : "OK"
}

我想从响应的几何部分中提取位置,但认为我误解了如何到达那里。欢迎任何帮助,因为我是新手。

当我运行它时,我被重定向到我的错误消息,所以我认为它只是没有找到经度或纬度。

请询问您是否对我的代码有任何疑问。

标签: jsonswift

解决方案


因此,让我们从原始响应开始。你有一个根 -results然后你有一个带有子geometry节点的节点location

1.我们将使用Codable协议使解析更容易:

struct RawResponseRoot: Codable {
    let results: [RawResponse]
}

struct RawResponse: Codable {

    struct Geometry: Codable {
        let location: Location
    }

    struct Location: Codable {
        private enum CodingKeys: String, CodingKey {
            case latitude = "lat", longitude = "lng"
        }
        let latitude: Double
        let longitude: Double
    }

    let name: String
    let geometry: Geometry
}

2. 创建一个 Venue 结构来保存您的位置和位置名称:

struct Venue: Codable {
    let name: String
    let latitude: Double
    let longitude: Double

    init(from rawResponse: RawResponse) throws {
        self.name = rawResponse.name
        self.latitude = rawResponse.geometry.location.latitude
        self.longitude = rawResponse.geometry.location.longitude
    }
}

3. 然后在您的 getData 函数中提取结果:

func getData(){
    let url = "URL FOR THE JSON"
    let urlOBJ = URL(string: url)

    URLSession.shared.dataTask(with: urlOBJ!){(data,response,error) in
          guard let data = data, let root = try? JSONDecoder().decode(RawVenueResponseRoot.self, from: data) else {
              print("Error retrieving data:", error)
              return
          }

        let locations = root.results.compactMap({ try? Venue(from: $0) })

}.resume()

推荐阅读