I'm a French Newbie in Swift and I want to make a Map with annotations from a JSON file using UIKit and MapKit. I use UIKit because I would like to use a lot of annotations and I want that the annotations collapse into a cluster Annotation if the user zoom out.
So, the project Built, but none of my annotations are displayed
Thanks a lot for anyone who correct my code. If you have questions, do not hesitate to ask me. Thanks you in advance.
So here my ViewController :
'''
import CoreLocation
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
var locations = [Location]()
@IBOutlet weak var mapView: MKMapView!
let manager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
mapView.register(LocationDataMapClusterView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier)
}
func AnnotationView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
switch annotation {
case is MKClusterAnnotation:
return mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier, for: annotation)
default:
return nil
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.delegate = self
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
mapView.showsUserLocation = true
readFile()
mapView.addAnnotations(locations)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first {
manager.stopUpdatingLocation()
render(location)
}
}
func render(_ location:CLLocation){
let coordinate = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
let region = MKCoordinateRegion(center: coordinate,
span: span)
mapView.setRegion(region, animated: true)
}
public func readFile() {
if let url = Bundle.main.url(forResource : "capital", withExtension: "json"),
let data = try? Data(contentsOf: url) {
let decoder = JSONDecoder()
if let jsonData = try? decoder.decode(JsonData.self, from: data){
self.locations = jsonData.locations
print(locations)
}
}
}
}
'''
My JSONFile :
'''
{
"locations": [
{
"id": 0,
"name": "New York City",
"latitude": 40.71,
"longitude": -74
},
{
"id": 1,
"name": "Barcelona",
"latitude": 41.38,
"longitude": 2.17
},
{
"id": 2,
"name": "Tokyo",
"latitude": 35.68,
"longitude": 139.76
},
{
"id": 3,
"name": "Atlanta",
"latitude": 33.74,
"longitude": -84.38
},
{
"id": 4,
"name": "Paris",
"latitude": 48.85,
"longitude": 2.35
},
{
"id": 5,
"name": "Hong Kong",
"latitude": 22.31,
"longitude": 114.16
}
]
}
'''
and my location class :
'''
import MapKit
import UIKit
class Location: NSObject, Decodable, Identifiable, MKAnnotation {
var id: Int
var name: String
var latitude: Double
var longitude : Double
var coordinate: CLLocationCoordinate2D {
.init(latitude: latitude, longitude: longitude)
}
init(id : Int, name : String, latitude : Double, longitude : Double){
self.id = id
self.name = name
self.longitude = longitude
self.latitude = latitude
}
}
struct JsonData : Decodable {
let locations : [Location]
}
'''
After some research I found my issue :
'''
mapView.addAnnotations(jsonData.locations)
'''
'''
public func readFile() {
if let url = Bundle.main.url(forResource : "capital", withExtension: "json"),
let data = try? Data(contentsOf: url) {
let decoder = JSONDecoder()
if let jsonData = try? decoder.decode(JsonData.self, from: data){
self.locations = jsonData.locations
mapView.addAnnotations(jsonData.locations)
}
}
}
'''
'''
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.delegate = self
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
mapView.showsUserLocation = true
readFile()
}
'''