DEV Community

Avelyn Hyunjeong Choi
Avelyn Hyunjeong Choi

Posted on

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

Top comments (0)