DEV Community

Avelyn Hyunjeong Choi
Avelyn Hyunjeong Choi

Posted on

2

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

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

Top comments (0)

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →