Maps with Swift II
Tags: swift, mobile, beginners
Published: 2023-11-22 15:36:58

In todays's blog, we will be extending our map application using `CLLocationManagerDelegate`.

1.Import CoreLocation
```swift
// we need this for getting the user's location
import CoreLocation
```

2.Create an instance of CLLocationManager
```swift
let locationManager = CLLocationManager()
```

3.Use the instance in `viewDidLoad()`
```swift
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
mapView.showsUserLocation = true
```

4.Create an array
```swift
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
```swift
    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`
```swift
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`
```swift
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)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yknjeyf83j1favv5jidf.png)

10.Set location to Apple to be able to use locations in Apple

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ce34eca0ujbfbrqcuws1.png)

11.Demo

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bdjkc8ldk0ijjx92tgq8.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/anm0wvurzfg354n6ehty.png)