Show Locations On Map Using MapKit and CoreLocation

How to show locations on a map using MapKit and CoreLocation?

In this article, we will learn how to use MapKit and CoreLocation in Swift and create a simple demo to display some of the well-known locations on the map. We will use MapKit to display a map inside our App and CoreLocation framework to get the geographic location data.

Pre-requisites

  • XCode
  • MacOS

Implementation

  •  Create a new project in XCode. Select iOS -> App -> Name your Project -> Save It to your desired location.
  •  We will start implementing our demo app by adding the permissions for our App to access the locations. Go to Info.plist file -> Right-click anywhere inside Info.plist File -> Select 'Add Row' -> In place of 'Bundle Identifier', paste 'NSLocationAlwaysAndWhenInUseUsageDescription'. Keep the Type as 'String' and enter 'Value' as 'This App wants to access your location.' or whatever message you would like to display on your App. Repeat the same step 2 more times and paste 'NSLocationAlwaysUsageDescription' and 'NSLocationWhenInUseUsageDescription' in place of 'Bundle Identifier'.
  • After following the above step, your Info.plist should look in this manner.
    Permissions
  • By adding the following permissions in the Info.plist File, your App will ask for permission to enable the location of your device.
  • Next, let's go to our storyboard 'Main'. I have created a simple tableview with a list of some of the tourist attractions of India. So our aim should be to click on any of the cells; our App must display the location on the map.
  • Lets, begin by creating a tableview. I have embedded my ViewController into NavigationController. To do this, select the View Controller -> Click on 'Editor' -> 'Embed In' -> 'Navigation Controller'.
  • So now you'll see that the View Controller is embedded into Navigation Controller.
  • Next, add a TableView to your ViewController and increase the count of Prototype Cells to 1 in the Attributes Inspector. Also, select the Table View Cell and name its identifier as 'cell' or whatever you would like to name it. Also, add the outlet of tableView to your ViewController.swift File.
  • Also, do not forget to add the dataSource and delegate of the table view. (Select the Table View -> Press 'Control' and drag the cursor to the little yellow button on top of View Controller -> Release the Cursor -> Select dataSource and delegate.)
    Navigations Controller
  • Once the above steps are done, we will go to our ViewController.swift File.
  • Paste the below code in ViewController.swift File.
    import UIKit
    
    class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
        @IBOutlet weak var tblView: UITableView!
    
        let annotationLocations: [[String: Any]] = [
        ["title": "Mysore Palace", "latitude": 12.30544, "longitude": 76.65515],
        ["title": "Gateway Of India, Mumbai", "latitude": 18.92222, "longitude": 72.83463],
        ["title": "Red Fort", "latitude": 28.65645, "longitude": 77.24098],
        ["title": "Hawa Mahal", "latitude": 26.92417, "longitude": 75.82675]
        ]
    
        override func viewDidLoad() {
            super.viewDidLoad()
            navigationItem.title = "List of Locations"
        }
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            annotationLocations.count
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let locationNames = annotationLocations[indexPath.row]
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
            cell.textLabel?.text = locationNames["title"] as? String
            return cell
        }
    }
    
    
  • By adding the above code, you must be able to see the list of the locations once you run the App on the simulator.
    List
  • Moving forward, now we will add a new ViewController on our Main.storyboard. This ViewController will be responsible for displaying the selected location on the map.
  • Go to Main.storyboard and add a new View Controller. In this new View Controller, add a Map Kit View. Add the delegate of this Map Kit View (Follow the same step as explained for the table view).
  • Now let's create a new Cocoa Touch File for this new View Controller.
  • Go to File -> New -> File -> iOS -> Cocoa Touch Class -> Next -> Name the Class as 'MapKitViewControllet' -> Select 'Subclass of:' as 'UIViewController' -> Next -> Create.
  • Now let's assign this newly created MapKitViewController to our new view controller.
  • Go to Main.storyboard file. Select the new View Controller. Go to 'Identity Inspector'. Assign the class as 'MapKitViewController' as shown in the below image.
  • Also, add a Storyboard ID as shown in the below image.
    Identity Inspector
  • Now you can add an outlet of Map Kit View in the MapKitViewController.
  • Go to MapKitViewController and paste the following code.
    import MapKit
    import CoreLocation
    
    class MapKitViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
        @IBOutlet weak var mapView: MKMapView!
        private var locationManager: CLLocationManager!
        private var currentLocation: CLLocation?
        var locationName: String!
        var locationLatitude: Any!
        var locationLongitude: Any!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            locationManager = CLLocationManager()
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
    
            // Check for Location Services
            if CLLocationManager.locationServicesEnabled() {
                locationManager.requestWhenInUseAuthorization()
                locationManager.startUpdatingLocation()
            }
        }
    
        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            // Zoom to user location
            let viewRegion = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: locationLatitude as! CLLocationDegrees, longitude: locationLongitude as! CLLocationDegrees), latitudinalMeters: 2000, longitudinalMeters: 2000)
            mapView.setRegion(viewRegion, animated: false)
            // To show the pin symbol on the map
            let mapAnnotation = MKPointAnnotation()
            mapAnnotation.title = locationName
            mapAnnotation.coordinate = CLLocationCoordinate2D(latitude: locationLatitude as! CLLocationDegrees, longitude: locationLongitude as! CLLocationDegrees)
            mapView.addAnnotation(mapAnnotation)
        }
    }
    
  • In the above code, you can see we have used 'CLLocationManagerDelegate' and 'MKMapViewDelegate', which are the delegates of CoreLocation and MapKit, respectively.
  • Also, in the ViewController.swift File, add the following tableView code.
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            let locationNames = annotationLocations[indexPath.row]
            let mapVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "MapView") as? MapKitViewController
            mapVC?.locationName = locationNames["title"] as? String
            mapVC?.locationLatitude = locationNames["latitude"]
            mapVC?.locationLongitude = locationNames["longitude"]
            self.navigationController?.pushViewController(mapVC!,animated: true)
        }
  • That's It! Now run the App and see the locations on the Map. 
    Final
  • This is a simple Demo App that I have created with the moto of self-learning. Any suggestions/feedback are happily accepted. Happy Coding!


Similar Articles