Avelyn Hyunjeong Choi
Posted on November 22, 2023
In todays's blog, we will be extending our map application using CLLocationManagerDelegate
.
1.Import CoreLocation
// we need this for getting the user's location
import CoreLocation
2.Create an instance of CLLocationManager
let locationManager = CLLocationManager()
3.Use the instance in viewDidLoad()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
mapView.showsUserLocation = true
4.Create an array
let wonders =
[
["title": "The Great Wall of China", "latitude": "40.431908", "longitude": "116.570374"],
["title": "Chichén-Itzá, Mexico", "latitude": "20.682985", "longitude": "-88.568649"],
["title": "Petra, Jordan", "latitude": "30.328960", "longitude": "35.444832"],
["title": "Machu Picchu, Peru", "latitude": "-13.163068", "longitude": "-72.545128"],
["title": "Christ the Redeemer, Rio de Janiero", "latitude": "-22.908333", "longitude": "-43.196388"],
["title": "Colosseum, Rome", "latitude": "41.890251", "longitude": "12.492373"],
["title": "Taj Mahal, India", "latitude": "27.173891", "longitude": "78.042068"],
]
5.Create a function to add pins to the location of wonders(array) on the map
private func show7Wonders() {
for wonder in wonders {
let annotation = MKPointAnnotation()
let title:String = wonder["title"]!
let latitude:CLLocationDegrees = Double(wonder["latitude"]!)!
let longitude:CLLocationDegrees = Double(wonder["longitude"]!)!
annotation.title = title
annotation.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
mapView.addAnnotation(annotation)
}
}
6.Add show7Wonders() in ViewDidLoad()
7.Create an extension of CLLocationManagerDelegate
extension MapVC: CLLocationManagerDelegate {
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
let status = manager.authorizationStatus
switch status {
case .notDetermined:
manager.requestWhenInUseAuthorization()
case .restricted:
print("auth status is restricted")
case .denied:
print("auth status is denied")
case .authorizedAlways:
print("auth status is authorizedAlways")
case .authorizedWhenInUse:
print("auth status is authorizedWhenInUse")
default:
print("faced some error in auth status")
}
}
}
8.Create an extension of MKMapViewDelegate
extension MapVC: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard annotation is MKPointAnnotation else { return nil }
let identifier = "Annotation"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
// when view does not exist
if annotationView == nil {
annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView?.detailCalloutAccessoryView = UIView()
annotationView?.canShowCallout = true
} else { // when the view already exists
annotationView!.annotation = annotation
}
return annotationView
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
let source = MKPlacemark(coordinate: mapView.userLocation.coordinate)
let destination = MKPlacemark(coordinate: view.annotation!.coordinate)
let sourceMapItem = MKMapItem(placemark: source)
let destinationMapItem = MKMapItem(placemark: destination)
let directionRequest = MKDirections.Request()
directionRequest.source = sourceMapItem
directionRequest.destination = destinationMapItem
// use static transportType here
directionRequest.transportType = .automobile
let directions = MKDirections(request: directionRequest)
// calculate direction
directions.calculate { [weak self] (response, error) in
print("response: \(response). error: \(error)")
if let response = response, error == nil {
let route = response.routes[0]
self?.mapView.addOverlay(route.polyline)
let rect = route.polyline.boundingMapRect
self?.mapView.setRegion(MKCoordinateRegion(rect), animated: true)
} else {
let overlays = mapView.overlays
self?.mapView.removeOverlays(overlays)
}
}
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = .systemBlue
renderer.lineWidth = 5.0
return renderer
}
9.We need to ask user for the permissions before app starts. To do that, go to Info
file and add key (Privacy - Location When In Use Usage Description)
10.Set location to Apple to be able to use locations in Apple
11.Demo
💖 💪 🙅 🚩
Avelyn Hyunjeong Choi
Posted on November 22, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.