I am new in swift , I implemented a MapKit with static data , and it worked fine , and I called after that backend pins data and it showed in the playground that it works fine , but the map is not displaying the markers , it seems that the mapKit do not capture the pins data in the right time , so I used Dispatch.Que to refresh the map but I did not refresh and it is displaying without the markers
here what I have tried :
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()
}
}
What I am trying to do is to make the mapkit capture the pins data in the right time and refresh it’s data, I think it is the only way to display my pins correctly
2
Answers
Getting the data is an async task. In the question you are updating the data before the network request has ended.
Combining this question with this one Set MapKit pins with different colors and the answer by Rob you could assign each URL path to the place type:
and then you could fetch the data in a for loop for each place type. Each time you call the method to fetch data, you’d pass a callback to add the returned places to the map:
The
fetchData
method just starts the network request and calls the completion method when done:The
Place
class would be the same one as in the answer from Rob, but with decoding and encoding logic:You can see the complete working code here. Feel free to ask questions in Github about the code if you do not understand something.