我从API检索了json数据(纬度和经度),我想在mapView中放置标记。效果很好,但是如果用户放大或缩小,我想更改标记。我找不到从多个函数使用数据的方法,或者我不知道在课堂上全局使用它。我尝试制作var listLocations = [Locations]()
Array
,但找不到获取数据的方法。
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
getLocations { (result) in
switch result {
case .success(let locations):
locations.forEach({ (locations) in
let lat = locations.location.latitude
let lon = locations.location.longitude
DispatchQueue.main.async{
let marker = GMSMarker()
marker.position = CLLocationCoordinate2DMake(lat, lon)
marker.map = self.mapView
let camera = GMSCameraPosition.camera(withLatitude: lat, longitude:lon, zoom:8)
self.mapView.animate(to: camera)
}
})
case .failure(let error):
print("Failed to load Locations", error)
}
}
//let location = locations.last
self.locationManager.stopUpdatingLocation()
}
来自API的请求
func getLocations(completion: @escaping(Result<[Locations], Error>) -> ()) {
let urlString = "API URL HERE"
guard let url = URL(string: urlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error {
completion(.failure(error))
return
}
do {
let locations = try JSONDecoder().decode([Locations].self, from: data!)
completion(.success(locations))
} catch let jsonError{
completion(.failure(jsonError))
}
}.resume()
}
结构
struct Locations: Codable {
let id: Int
let location: AreaElement
let name: Name?
let type: String
let area: [AreaElement]?
enum CodingKeys: String, CodingKey {
case id = "ID"
case location = "Location"
case name = "Name"
case type = "Type"
case area = "Area"
}
}
struct AreaElement: Codable {
let latitude, longitude: Double
enum CodingKeys: String, CodingKey {
case latitude = "Latitude"
case longitude = "Longitude"
}
}
struct Name: Codable {
let latin, local: String?
enum CodingKeys: String, CodingKey {
case latin = "Latin"
case local = "Local"
}
}
您需要保留对标记的引用(让marker = GMSMarker())。您可以随时更改标记的位置。