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

时间:2018-12-06 10:56:30

标签: swift swift4

我正在学习快速。

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

<div id=\"tps_nav_upper_1785\" class=\"theiaPostSlider_nav _right fontTheme _upper\"><div class=\"_buttons\"><span class=\"_button _prev _another_post _disabled\"><span class=\"_1\"></span><span class=\"_2\" ><span aria-hidden=\"true\" class=\"tps-icon-chevron-circle-left\"></span></span><span class=\"_3\">Anterior</span></span><span class=\"_text\">1 de 15</span><a href=\"https://litoralmagazine.com/testemunhos-litoral-awards/2/\" class=\"_button _next\"><span class=\"_1\">Seguinte</span><span class=\"_2\" ><span aria-hidden=\"true\" class=\"tps-icon-chevron-circle-right\"></span></span><span class=\"_3\"></span></a></div><div class=\"_title\"><span class=\"_helper\"></span></div></div><div id=\"tps_slideContainer_1785\" class=\"theiaPostSlider_slides\"><div>\n\n<div id=\"attachment_1958\" style=\"width: 210px\" class=\"wp-caption alignleft\"><img class=\"wp-image-1958 size-medium\" src=\"https://litoralmagazine.com/wp-content/uploads/2014/11/ribau-esteves-200x300.jpg\" alt=\"ribau-esteves\" width=\"200\" height=\"300\" srcset=\"https://litoralmagazine.com/wp-content/uploads/2014/11/ribau-esteves-200x300.jpg 200w, https://litoralmagazine.com/wp-content/uploads/2014/11/ribau-esteves-600x900.jpg 600w, https://litoralmagazine.com/wp-content/uploads/2014/11/ribau-esteves.jpg 601w\" sizes=\"(max-width: 200px) 100vw, 200px\" /><p class=\"wp-caption-text\">Ribau Esteves &#8211; Presidente da Câmara Municipal de Aveiro</p></div>\n<p style=\"text-align: left;\">A edição de 2015 da Gala Litoral Awards marcou a agenda do município e da região de Aveiro, num exercício elegante e justo que reconhece e motiva todos para fazermos mais e melhor pela vida, pelas empresas, pelos municípios, pela região e pelas pessoas. Fazer muito e bem tem de ser, cada vez mais, uma tarefa importante e permanente. Reconhecer e premiar o mérito são atos nobres e necessários, para que juntos possamos continuar a crescer.</p>\n<h6 style=\"text-align: left;\">\n\n</div></div><div id=\"tps_nav_lower_1785\" class=\"theiaPostSlider_nav _right fontTheme _lower\"><div class=\"_buttons\"><span class=\"_button _prev _another_post _disabled\"><span class=\"_1\"></span><span class=\"_2\" ><span aria-hidden=\"true\" class=\"tps-icon-chevron-circle-left\"></span></span><span class=\"_3\">Anterior</span></span><span class=\"_text\">1 de 15</span><a href=\"https://litoralmagazine.com/testemunhos-litoral-awards/2/\" class=\"_button _next\"><span class=\"_1\">Seguinte</span><span class=\"_2\" ><span aria-hidden=\"true\" class=\"tps-icon-chevron-circle-right\"></span></span><span class=\"_3\"></span></a></div><div class=\"_title\"><span class=\"_helper\"></span></div></div><div class=\"theiaPostSlider_footer _footer\"></div><p><!-- END THEIA POST SLIDER --></p>\n\n                <script type='text/javascript'>\n                    \n                var tpsInstance;\n                var tpsOptions = {\"slideContainer\":\"#tps_slideContainer_1785\",\"nav\":[\".theiaPostSlider_nav\"],\"navText\":\"%{currentSlide} de %{totalSlides}\",\"helperText\":\"\",\"defaultSlide\":0,\"transitionEffect\":\"slide\",\"transitionSpeed\":400,\"keyboardShortcuts\":true,\"scrollAfterRefresh\":true,\"numberOfSlides\":15,\"slides\":[],\"useSlideSources\":true,\"themeType\":\"font\",\"prevText\":\"Anterior\",\"nextText\":\"Seguinte\",\"buttonWidth\":\"0\",\"buttonWidth_post\":\"0\",\"postUrl\":\"https:\\/\\/litoralmagazine.com\\/testemunhos-litoral-awards\\/\",\"postId\":1785,\"refreshAds\":false,\"refreshAdsEveryNSlides\":\"1\",\"adRefreshingMechanism\":\"javascript\",\"siteUrl\":\"https:\\/\\/litoralmagazine.com\",\"loopSlides\":false,\"scrollTopOffset\":\"0\",\"prevFontIcon\":\"<span aria-hidden=\\\"true\\\" class=\\\"tps-icon-chevron-circle-left\\\"><\\/span>\",\"nextFontIcon\":\"<span aria-hidden=\\\"true\\\" class=\\\"tps-icon-chevron-circle-right\\\"><\\/span>\"};\n            \n                    (function ($) {\n                        $(document).ready(function () {\n                            \n                            tpsInstance = new tps.createSlideshow(tpsOptions);\n                        });\n                    }(jQuery));\n                </script>\n 

我无法解析此json并从lat和lon中获取数据以及从供应商处获取名称。

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

我的视图确实加载了方法

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

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

       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    
    }

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

3 个答案:

答案 0 :(得分:3)

发生错误是因为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()

...

答案 1 :(得分:1)

您可以尝试

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 {$0.vendor.latitude })

答案 2 :(得分:0)

看到这个

 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
            }
        }
    }
}

enter image description here