Maps with Swift II

avelynhc

Avelyn Hyunjeong Choi

Posted on November 22, 2023

Maps with Swift II

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
Enter fullscreen mode Exit fullscreen mode

2.Create an instance of CLLocationManager

let locationManager = CLLocationManager()
Enter fullscreen mode Exit fullscreen mode

3.Use the instance in viewDidLoad()

locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
mapView.showsUserLocation = true
Enter fullscreen mode Exit fullscreen mode

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"],
]
Enter fullscreen mode Exit fullscreen mode

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)
        }
    }
Enter fullscreen mode Exit fullscreen mode

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")
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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
    }
Enter fullscreen mode Exit fullscreen mode

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

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

Image description

11.Demo

Image description

Image description

💖 💪 🙅 🚩
avelynhc
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.

Related