无法从嵌套的 json swift 中获取数据

Unable to get the data from a nested json swift

我正在学习swift。

我有一个来自服务器的 json。

[
  {
    "dId": 1,
    "vendor": {
      "vendorId": 1,
      "name": "Gems",
      "about": "Get Good quality stones",
      "address": "JacksonVille Road",
      "latitude": 12.232323,
      "longitude": 77.230802,
    },
    "name": "Gems Delight",
  }
]

我无法解析此 json 并从经纬度和供应商处获取数据。

我的 url 方法和我的 for 循环如何从循环中准确获取经纬度并将它们放在地图上?

我的视图确实加载了方法

       override func viewDidLoad() {
        super.viewDidLoad()

        guard let gitUrl = URL(string: "localhost:8080/deals") else { return }
        URLSession.shared.dataTask(with: gitUrl) { (data, response
            , error) in
            guard let data = data else { return }
            do {
                let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)

                var lat:Double
                var lon:Double
                var nam = ""
                for items in json as! [AnyObject]{
//                    let te = type(of: items)
//                    print(te)
                    let new = items["vendor"]

                    for (it,key) in new as! [String:Any]{
//                        print(it,key)
//                        print(it["longitude"])

                        if it == "longitude"{
                            print(it,key)
                            lon = key as! Double
                        }
                        if it == "latitude"{
                            print(it,key)
                            lat = key as! Double
                        }

                        if it == "name"{
                            nam = key as! String


                        }

                            if (nam.isEmpty == false){
                            print("falsdalsdasldasd")
                            self.locationManager.delegate = self
                            self.locationManager.requestWhenInUseAuthorization()
                            self.locationManager.startUpdatingLocation()
                            let camera = GMSCameraPosition.camera(withLatitude:lat, longitude:lon, zoom: 4.0)
                            let subView = GMSMapView.map(withFrame: self.view.bounds,camera:camera)
                            let marker = GMSMarker()
                            marker.position = CLLocationCoordinate2D(latitude:lat, longitude:lon)
                            marker.title = nam
                            //                        marker.snippet = "Australia"
                            marker.map = subView

                            self.mapView.addSubview(subView)
                        }




//                        print(it["longitude"])

                    }
//                    let te = type(of: items)
//                    for it in new as![AnyObject]{
////                        print(it"])
//                        print(it)
//
//                    }
//                    print(items["vendor"].["latitude"])
//                    print(items.vendor)
//                    print(items[""])
//                    let nam = items["name"];
//                    let desc = items["description"];
//                    self.locationNames.append(nam as! String)
//                    self.locationDescription.append(desc as! String)
//

                }
//                self.colecVw.delegate = self
//                self.colecVw.dataSource = self
//                self.colecVw.reloadData()

                //                }

            } catch let err {
                print("Err", err)
            }
            }.resume()


        print("coming here")


        //         Create a GMSCameraPosition that tells the map to display the
        //         coordinate -33.86,151.20 at zoom level 6.
        //       let mapView = GMSMapView(frame: CGRect(x: 0, y: 64, width: self.currentDeviceSize.width, height: self.bottomBgView.frame.minY - 64))
//        view = mapView
//
//        // Creates a marker in the center of the map.
//        let marker = GMSMarker()
//        marker.position = CLLocationCoordinate2D(latitude: -33.86, longitude: 151.20)
//        marker.title = "Sydney"
//        marker.snippet = "Australia"
//        marker.map = mapView    
    }

请帮助我,因为我正在学习编码,我的代码可能不正确,请不要介意并将纬度和经度数据加载到地图上。我应该构建一个对象并将它们放在那里吗?

Variable 'lon' used before being initialized
Variable 'lat' used before being initialized

这是我从代码中得到的错误。

你可以试试

struct Root: Codable {
    let dID: Int
    let vendor: Vendor
    let name: String

    enum CodingKeys: String, CodingKey {
        case dID = "dId"
        case vendor, name
    }
}

struct Vendor: Codable {
    let vendorID: Int
    let name, about, address: String
    let latitude, longitude: Double

    enum CodingKeys: String, CodingKey {
        case vendorID = "vendorId"
        case name, about, address, latitude, longitude
    }
}

--

let arr = try? JSONDecoder().decode([Root].self, from:data)

print(arr?.forEach {[=11=].vendor.latitude })

看到这个

 let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)

将json传给

 if let data = json as? NSArray {
    for data in data {
        if let data = data as? [String: AnyObject] {
            let dataID = data["dId"] as? Int

            if let data = data[“vendor”] as? [String: AnyObject] {
                let vendorID = data["vendorId"] as? Int
            }
        }
    }
}

错误发生是因为 latlon 必须 在行

中有一个值
let camera = GMSCameraPosition.camera(withLatitude:lat, longitude:lon, zoom: 4.0)

如果 key 比较失败,则无法保证。

条件满足

var lat = 0.0 // The type Double is inferred
var lon = 0.0

但不是枚举字典,而是通过可选绑定直接安全地获取键的值

do {
    // no mutableContainers !!
    let json = try JSONSerialization.jsonObject(with: data) as! [[String:Any]]

    for item in json {
        if let vendor = item["vendor"] as? [String:Any],
            let lat = vendor["latitude"] as? Double,
            let lon = vendor["longitude"] as? Double,
            let name = item["name"] as? String, !name.isEmpty {

            print("falsdalsdasldasd")
            // self.locationManager.delegate = self
            // self.locationManager.requestWhenInUseAuthorization()
            // self.locationManager.startUpdatingLocation()
            let camera = GMSCameraPosition.camera(withLatitude:lat, longitude:lon, zoom: 4.0)
            let subView = GMSMapView.map(withFrame: self.view.bounds,camera:camera)
            let marker = GMSMarker()
            marker.position = CLLocationCoordinate2D(latitude:lat, longitude:lon)
            marker.title = name
            marker.map = subView
            self.mapView.addSubview(subView)
        }
    }
} catch {
    print("Err", error)
}

并且在每次迭代中调用 LocationManager 方法是荒谬的。在 viewDidLoad

开头调用一次
override func viewDidLoad() {
    super.viewDidLoad()
    self.locationManager.delegate = self
    self.locationManager.requestWhenInUseAuthorization()
    self.locationManager.startUpdatingLocation()

...