首页 > 解决方案 > 遍历 JSON 数组并将坐标添加到地图

问题描述

我正在使用API来获取纬度和经度坐标,并将它们放置在地图上,并使用它对应的地点的名称。我可以放置一个地方的经纬度坐标,但我不太确定如何将它们全部添加到地图中。我不知道该怎么做。我尝试使用 for 循环来做到这一点,但我太确定我将如何实现它。这是我到目前为止所得到的:

    func getData() {
        let url = "https://www.givefood.org.uk/api/2/foodbanks/"
        let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler: { [self] data, response, error in
            guard let data = data, error == nil else {
                print("Wrong")
                return
            }

            var result: [Info]?

            do {
                result = try JSONDecoder().decode([Info].self, from: data)
            }
            catch {
                print("Failed to convert: \(error.localizedDescription)")
            }
            guard let json = result else {
                return
            }
            
            for each in json {
                
                var each = 0
                each += 1
                
                let comp = json[each].lat_lng?.components(separatedBy: ",")
                
                let latString = comp![each]
                let lonString = comp![each]

                let lat = Double(latString)
                let lon = Double(lonString)
                
                let locationPin: CLLocationCoordinate2D = CLLocationCoordinate2DMake(lat!, lon!)
                
                let location: CLLocationCoordinate2D = CLLocationCoordinate2DMake(51.55573, -0.108312)
                
                let region = MKCoordinateRegion.init(center: location, latitudinalMeters: regionInMetres, longitudinalMeters: regionInMetres)
                
                mapView.setRegion(region, animated: true)

                let myAn1 = MapPin(title: json[each].name!, locationName: json[each].name!, coordinate: locationPin)
                
                mapView.addAnnotations([myAn1])
            }
        })
        task.resume()
    }

标签: iosarraysswift

解决方案


您的循环是错误的,each之后for是一项InfoInt索引each毫无意义,您在每次迭代中将其设置为零,因此您始终获得相同的坐标(在索引 1 处)。

首先声明namelat_lng作为非可选的。所有记录都包含这两个字段。

struct Info : Decodable {
    let lat_lng : String
    let name : String
}

其次,为了方便起见,扩展CLLocationCoordinate2D为从字符串创建坐标

extension CLLocationCoordinate2D {
    init?(string: String) {
        let comp = string.components(separatedBy: ",")
        guard comp.count == 2, let lat = Double(comp[0]), let lon = Double(comp[1]) else { return nil }
        self.init(latitude: lat, longitude: lon )
    }
}

第三,将所有好的代码放入do范围而不是处理选项,并在循环之前设置一次区域

func getData() {
    let url = "https://www.givefood.org.uk/api/2/foodbanks/"
    let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler: { [self] data, response, error in
        if let error = error { print(error); return }
        
        do {
            let result = try JSONDecoder().decode([Info].self, from: data!)
            let location = CLLocationCoordinate2D(latitude: 51.55573, longitude: -0.108312)
            let region = MKCoordinateRegion.init(center: location, latitudinalMeters: regionInMetres, longitudinalMeters: regionInMetres)
            mapView.setRegion(region, animated: true)
            var pins = [MapPin]()
            for info in result {
                if let coordinate = CLLocationCoordinate2D(string: info.lat_lng) {                      
                    pins.append(MapPin(title: info.name, locationName: info.name, coordinate: coordinate))
                    
                }
            } 
            DispatchQueue.main.async {
                self.mapView.addAnnotations(pins)
            }
        }
        catch {
            print("Failed to convert: \(error)")
        }
    })
    task.resume()
}

推荐阅读