调用 urlsession 数据后重新加载地图
reload map after calling urlsession data
我是 swift 的新人,我实现了一个带有静态数据的 MapKit,它工作正常,我调用了那个后端引脚数据,它在操场上显示它工作正常,但是地图不显示标记,似乎 mapKit 没有在正确的时间捕获引脚数据,所以我使用 Dispatch.Que 刷新地图但我没有刷新,它显示没有标记
这是我尝试过的:
import UIKit
import MapKit
class myMapViewController: UIViewController, MKMapViewDelegate {
var shops = [Shops]()
var communities = [Community]()
var cyclists = [Cyclist]()
var circuits = [Circuit]()
var BR = BaseUrl.baseUrl
@IBOutlet weak var myMap: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
self.getShops()
self.getCircuits()
self.getCyclists()
self.getCommunities()
//shops.append(Shops(id: 0, title: "Shop1", latitude: 36.553015 , longitude: 10.592774))
//shops.append(Shops(id: 0, title: "Shop2", latitude: 35.499414 , longitude: 10.824846))
//communities.append(Community(id: 0, title: "community1", latitude: 37.276943 , longitude: 10.934709 ))
//communities.append(Community(id: 0, title: "community2", latitude: 35.427828 , longitude: 9.748186 ))
//circuits.append(Circuit(id: 0, title: "circuit1", latitude: 33.773035 , longitude: 10.857805 ))
//cyclists.append(Cyclist(id: 0, title: "cyclist1", latitude: 35.785118 , longitude: 10.000871 ))
createShopsAnnotations(locations: shops)
createCircuitsAnnotations(locations: circuits)
createCommunityAnnotations(locations: communities)
createCyclistsAnnotations(locations: cyclists)
}
func createShopsAnnotations(locations:[Shops]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}}
func createCircuitsAnnotations(locations:[Circuit]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}
}
func createCommunityAnnotations(locations:[Community]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}}
func createCyclistsAnnotations(locations:[Cyclist]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}}
func getShops(){
//get
guard let url = URL(string: BR+"/shops") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.shops.removeAll()
for item in json {
let id = item["shop_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.shops.append(Shops(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.shops {
print(item.shop_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
}catch{
print(error)
}
}
}.resume()
}
func getCommunities(){
//get
guard let url = URL(string: BR+"/communities") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.communities.removeAll()
for item in json {
let id = item["community_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.communities.append(Community(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.communities {
print(item.community_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
}catch{
print(error)
}
}
}.resume()
}
func getCircuits(){
//get
guard let url = URL(string: BR+"/circuits") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.shops.removeAll()
for item in json {
let id = item["circuit_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.circuits.append(Circuit(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.circuits {
print(item.circuit_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
}catch{
print(error)
}
}
}.resume()
}
func getCyclists(){
//get
guard let url = URL(string: BR+"/cyclists") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.cyclists.removeAll()
for item in json {
let id = item["cyclist_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.cyclists.append(Cyclist(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.cyclists {
print(item.cyclist_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
}catch{
print(error)
}
}
}.resume()
}
}
我想做的是让 mapkit 在正确的时间捕获图钉数据并刷新它的数据,我认为这是正确显示我的图钉的唯一方法
import UIKit
import MapKit
class myMapViewController: UIViewController, MKMapViewDelegate {
var shops = [Shops]()
var communities = [Community]()
var cyclists = [Cyclist]()
var circuits = [Circuit]()
var BR = BaseUrl.baseUrl
@IBOutlet weak var myMap: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
self.myMap.delegate = self
self.getCircuits()
self.getCyclists()
self.getCommunities()
//shops.append(Shops(id: 0, title: "Shop1", latitude: 36.553015 , longitude: 10.592774))
//shops.append(Shops(id: 0, title: "Shop2", latitude: 35.499414 , longitude: 10.824846))
//communities.append(Community(id: 0, title: "community1", latitude: 37.276943 , longitude: 10.934709 ))
//communities.append(Community(id: 0, title: "community2", latitude: 35.427828 , longitude: 9.748186 ))
//circuits.append(Circuit(id: 0, title: "circuit1", latitude: 33.773035 , longitude: 10.857805 ))
//cyclists.append(Cyclist(id: 0, title: "cyclist1", latitude: 35.785118 , longitude: 10.000871 ))
createShopsAnnotations(locations: shops)
createCircuitsAnnotations(locations: circuits)
createCommunityAnnotations(locations: communities)
createCyclistsAnnotations(locations: cyclists)
}
func createShopsAnnotations(locations:[Shops]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}}
func createCircuitsAnnotations(locations:[Circuit]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}
}
func createCommunityAnnotations(locations:[Community]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}}
func createCyclistsAnnotations(locations:[Cyclist]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}}
func getShops(){
//get
guard let url = URL(string: BR+"/shops") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.shops.removeAll()
for item in json {
let id = item["shop_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.shops.append(Shops(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.shops {
print(item.shop_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
self.createShopsAnnotations(locations: self.shops)
}catch{
print(error)
}
}
}.resume()
}
func getCommunities(){
//get
guard let url = URL(string: BR+"/communities") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.communities.removeAll()
for item in json {
let id = item["community_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.communities.append(Community(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.communities {
print(item.community_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
self.createCommunityAnnotations(locations: self.communities)
}catch{
print(error)
}
}
}.resume()
}
func getCircuits(){
//get
guard let url = URL(string: BR+"/circuits") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.shops.removeAll()
for item in json {
let id = item["circuit_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.circuits.append(Circuit(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.circuits {
print(item.circuit_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
self.createCircuitsAnnotations(locations: self.circuits)
}catch{
print(error)
}
}
}.resume()
}
func getCyclists(){
//get
guard let url = URL(string: BR+"/cyclists") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.cyclists.removeAll()
for item in json {
let id = item["cyclist_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.cyclists.append(Cyclist(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.cyclists {
print(item.cyclist_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
self.createCyclistsAnnotations(locations: self.cyclists)
}catch{
print(error)
}
}
}.resume()
}
}
获取数据是一个异步任务。在问题中,您正在网络请求结束之前更新数据。
将这个问题与这个 以及 Rob 的回答结合起来,您可以将每个 URL 路径分配给地点类型:
enum PlaceType {
case shop, community, cyclist, circuit
var urlPath: String {
switch self {
case .shop: return "/shops"
case .community: return "/communities"
case .circuit: return "/circuits"
case .cyclist: return "/cyclists"
}
}
然后您可以在 for 循环中为每个地点类型获取数据。每次调用该方法获取数据时,您都会传递一个回调以将返回的地点添加到地图中:
@IBOutlet weak var myMap: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
for placeType in PlaceType.allCases {
// Call each get method with a callback
fetchData(
for: placeType,
completion: { [weak self] places in
guard let self = self else { return }
self.myMap.addAnnotations(places)
}
)
}
}
fetchData
方法只是启动网络请求,完成后调用完成方法:
func fetchData(for placeType: PlaceType, completion: @escaping ([Place]) -> Void) {
guard let url = URL(string: BR + placeType.urlPath) else { return }
URLSession.shared.dataTask(with: url) { ( data , response, error) in
guard let data = data else { return }
do {
let places = try JSONDecoder().decode([Place].self, from: data)
completion(places) // this is the callback!
} catch {}
}.resume()
}
Place
class 与 中的相同,但具有解码和编码逻辑:
class Place: NSObject, MKAnnotation, Codable {
let id: Int
let type: PlaceType
let latitude: Double
let longitude: Double
dynamic var title: String?
lazy var coordinate: CLLocationCoordinate2D = {
CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}()
init(id: Int, title: String, latitude: Double, longitude: Double, type: PlaceType) {
self.id = id
self.type = type
self.title = title
self.latitude = latitude
self.longitude = longitude
super.init()
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
// Try to decode each place type id to see which place type the data is for
var type: PlaceType? = nil
var tempID: Int? = nil
PlaceType.allCases.forEach { placeType in
if let id = try? container.decode(Int.self, forKey: placeType.codingKey) {
type = placeType
tempID = id
}
}
guard let decodedType = type, let decodedID = tempID else {
let context = DecodingError.Context(
codingPath: decoder.codingPath,
debugDescription: "Data does not have data for any of existing place types"
)
throw DecodingError.valueNotFound(Place.self, context)
}
self.type = decodedType
self.id = decodedID
self.title = try container.decode(String.self, forKey: .title)
self.latitude = try container.decode(Double.self, forKey: .latitude)
self.longitude = try container.decode(Double.self, forKey: .longitude)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: type.codingKey)
try container.encode(title, forKey: .title)
try container.encode(latitude, forKey: .latitude)
try container.encode(longitude, forKey: .longitude)
}
enum CodingKeys: String, CodingKey {
case shop_id, community_id, circuit_id, cyclist_id
case title, latitude, longitude
}
}
您可以看到完整的工作代码here。如果您不明白某些内容,请随时在 Github 中提出有关代码的问题。
我是 swift 的新人,我实现了一个带有静态数据的 MapKit,它工作正常,我调用了那个后端引脚数据,它在操场上显示它工作正常,但是地图不显示标记,似乎 mapKit 没有在正确的时间捕获引脚数据,所以我使用 Dispatch.Que 刷新地图但我没有刷新,它显示没有标记
这是我尝试过的:
import UIKit
import MapKit
class myMapViewController: UIViewController, MKMapViewDelegate {
var shops = [Shops]()
var communities = [Community]()
var cyclists = [Cyclist]()
var circuits = [Circuit]()
var BR = BaseUrl.baseUrl
@IBOutlet weak var myMap: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
self.getShops()
self.getCircuits()
self.getCyclists()
self.getCommunities()
//shops.append(Shops(id: 0, title: "Shop1", latitude: 36.553015 , longitude: 10.592774))
//shops.append(Shops(id: 0, title: "Shop2", latitude: 35.499414 , longitude: 10.824846))
//communities.append(Community(id: 0, title: "community1", latitude: 37.276943 , longitude: 10.934709 ))
//communities.append(Community(id: 0, title: "community2", latitude: 35.427828 , longitude: 9.748186 ))
//circuits.append(Circuit(id: 0, title: "circuit1", latitude: 33.773035 , longitude: 10.857805 ))
//cyclists.append(Cyclist(id: 0, title: "cyclist1", latitude: 35.785118 , longitude: 10.000871 ))
createShopsAnnotations(locations: shops)
createCircuitsAnnotations(locations: circuits)
createCommunityAnnotations(locations: communities)
createCyclistsAnnotations(locations: cyclists)
}
func createShopsAnnotations(locations:[Shops]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}}
func createCircuitsAnnotations(locations:[Circuit]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}
}
func createCommunityAnnotations(locations:[Community]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}}
func createCyclistsAnnotations(locations:[Cyclist]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}}
func getShops(){
//get
guard let url = URL(string: BR+"/shops") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.shops.removeAll()
for item in json {
let id = item["shop_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.shops.append(Shops(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.shops {
print(item.shop_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
}catch{
print(error)
}
}
}.resume()
}
func getCommunities(){
//get
guard let url = URL(string: BR+"/communities") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.communities.removeAll()
for item in json {
let id = item["community_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.communities.append(Community(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.communities {
print(item.community_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
}catch{
print(error)
}
}
}.resume()
}
func getCircuits(){
//get
guard let url = URL(string: BR+"/circuits") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.shops.removeAll()
for item in json {
let id = item["circuit_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.circuits.append(Circuit(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.circuits {
print(item.circuit_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
}catch{
print(error)
}
}
}.resume()
}
func getCyclists(){
//get
guard let url = URL(string: BR+"/cyclists") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.cyclists.removeAll()
for item in json {
let id = item["cyclist_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.cyclists.append(Cyclist(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.cyclists {
print(item.cyclist_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
}catch{
print(error)
}
}
}.resume()
}
}
我想做的是让 mapkit 在正确的时间捕获图钉数据并刷新它的数据,我认为这是正确显示我的图钉的唯一方法
import UIKit
import MapKit
class myMapViewController: UIViewController, MKMapViewDelegate {
var shops = [Shops]()
var communities = [Community]()
var cyclists = [Cyclist]()
var circuits = [Circuit]()
var BR = BaseUrl.baseUrl
@IBOutlet weak var myMap: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
self.myMap.delegate = self
self.getCircuits()
self.getCyclists()
self.getCommunities()
//shops.append(Shops(id: 0, title: "Shop1", latitude: 36.553015 , longitude: 10.592774))
//shops.append(Shops(id: 0, title: "Shop2", latitude: 35.499414 , longitude: 10.824846))
//communities.append(Community(id: 0, title: "community1", latitude: 37.276943 , longitude: 10.934709 ))
//communities.append(Community(id: 0, title: "community2", latitude: 35.427828 , longitude: 9.748186 ))
//circuits.append(Circuit(id: 0, title: "circuit1", latitude: 33.773035 , longitude: 10.857805 ))
//cyclists.append(Cyclist(id: 0, title: "cyclist1", latitude: 35.785118 , longitude: 10.000871 ))
createShopsAnnotations(locations: shops)
createCircuitsAnnotations(locations: circuits)
createCommunityAnnotations(locations: communities)
createCyclistsAnnotations(locations: cyclists)
}
func createShopsAnnotations(locations:[Shops]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}}
func createCircuitsAnnotations(locations:[Circuit]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}
}
func createCommunityAnnotations(locations:[Community]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}}
func createCyclistsAnnotations(locations:[Cyclist]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
DispatchQueue.main.async {
self.myMap.addAnnotation(annotations)
}
}}
func getShops(){
//get
guard let url = URL(string: BR+"/shops") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.shops.removeAll()
for item in json {
let id = item["shop_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.shops.append(Shops(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.shops {
print(item.shop_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
self.createShopsAnnotations(locations: self.shops)
}catch{
print(error)
}
}
}.resume()
}
func getCommunities(){
//get
guard let url = URL(string: BR+"/communities") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.communities.removeAll()
for item in json {
let id = item["community_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.communities.append(Community(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.communities {
print(item.community_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
self.createCommunityAnnotations(locations: self.communities)
}catch{
print(error)
}
}
}.resume()
}
func getCircuits(){
//get
guard let url = URL(string: BR+"/circuits") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.shops.removeAll()
for item in json {
let id = item["circuit_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.circuits.append(Circuit(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.circuits {
print(item.circuit_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
self.createCircuitsAnnotations(locations: self.circuits)
}catch{
print(error)
}
}
}.resume()
}
func getCyclists(){
//get
guard let url = URL(string: BR+"/cyclists") else {
return
}
let session = URLSession.shared
session.dataTask(with: url) { ( data , response ,error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do
{
let json = try JSONSerialization.jsonObject(with: data, options: [])as! [[String:Any]]
self.cyclists.removeAll()
for item in json {
let id = item["cyclist_id"] as! Int
let title = item["title"] as! String
let latitude = item["latitude"] as! Double
let longitude = item["longitude"] as! Double
self.cyclists.append(Cyclist(id: id, title: title, latitude: latitude , longitude: longitude))
}
for item in self.cyclists {
print(item.cyclist_id)
print(item.title)
print(item.latitude)
print(item.longitude)
}
self.createCyclistsAnnotations(locations: self.cyclists)
}catch{
print(error)
}
}
}.resume()
}
}
获取数据是一个异步任务。在问题中,您正在网络请求结束之前更新数据。
将这个问题与这个
enum PlaceType {
case shop, community, cyclist, circuit
var urlPath: String {
switch self {
case .shop: return "/shops"
case .community: return "/communities"
case .circuit: return "/circuits"
case .cyclist: return "/cyclists"
}
}
然后您可以在 for 循环中为每个地点类型获取数据。每次调用该方法获取数据时,您都会传递一个回调以将返回的地点添加到地图中:
@IBOutlet weak var myMap: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
for placeType in PlaceType.allCases {
// Call each get method with a callback
fetchData(
for: placeType,
completion: { [weak self] places in
guard let self = self else { return }
self.myMap.addAnnotations(places)
}
)
}
}
fetchData
方法只是启动网络请求,完成后调用完成方法:
func fetchData(for placeType: PlaceType, completion: @escaping ([Place]) -> Void) {
guard let url = URL(string: BR + placeType.urlPath) else { return }
URLSession.shared.dataTask(with: url) { ( data , response, error) in
guard let data = data else { return }
do {
let places = try JSONDecoder().decode([Place].self, from: data)
completion(places) // this is the callback!
} catch {}
}.resume()
}
Place
class 与
class Place: NSObject, MKAnnotation, Codable {
let id: Int
let type: PlaceType
let latitude: Double
let longitude: Double
dynamic var title: String?
lazy var coordinate: CLLocationCoordinate2D = {
CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}()
init(id: Int, title: String, latitude: Double, longitude: Double, type: PlaceType) {
self.id = id
self.type = type
self.title = title
self.latitude = latitude
self.longitude = longitude
super.init()
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
// Try to decode each place type id to see which place type the data is for
var type: PlaceType? = nil
var tempID: Int? = nil
PlaceType.allCases.forEach { placeType in
if let id = try? container.decode(Int.self, forKey: placeType.codingKey) {
type = placeType
tempID = id
}
}
guard let decodedType = type, let decodedID = tempID else {
let context = DecodingError.Context(
codingPath: decoder.codingPath,
debugDescription: "Data does not have data for any of existing place types"
)
throw DecodingError.valueNotFound(Place.self, context)
}
self.type = decodedType
self.id = decodedID
self.title = try container.decode(String.self, forKey: .title)
self.latitude = try container.decode(Double.self, forKey: .latitude)
self.longitude = try container.decode(Double.self, forKey: .longitude)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: type.codingKey)
try container.encode(title, forKey: .title)
try container.encode(latitude, forKey: .latitude)
try container.encode(longitude, forKey: .longitude)
}
enum CodingKeys: String, CodingKey {
case shop_id, community_id, circuit_id, cyclist_id
case title, latitude, longitude
}
}
您可以看到完整的工作代码here。如果您不明白某些内容,请随时在 Github 中提出有关代码的问题。