MapKit Tutorial: Getting Started

Learn to use the powerful MapKit framework to build an interactive map, displaying location details and launching Maps for driving directions. By Andrew Tetlaw.

4.8 (34) · 4 Reviews

Download materials
Save for later
Share
Update note: Andrew Tetlaw updated this tutorial for iOS 13. Audrey Tam wrote the original.

MapKit is a powerful API available on iOS devices that makes it easy to display maps, mark locations, enhance with custom data and even draw routes or other shapes on top.

In this MapKit tutorial, you’ll make HonoluluArt, an app that zooms into a location in Honolulu and marks public artwork on a map. You’ll implement the marker’s callout detail button to launch the Maps app and open driving directions to the artwork. Then, you’ll parse a GeoJSON file from the Honolulu city data portal to extract the public artwork features and mark them on the map.

In the process, you’ll learn how to:

  • Add a MapKit map to your app.
  • Zoom to a particular location.
  • Parse GeoJSON data to create custom map annotations.
A note from the original author, Audrey Tam: This update uses public artworks data from Honolulu, where I was born and raised. It’s no longer my hometown, but the names and places bring back memories. If you’re not lucky enough to live there, I hope you’ll enjoy imagining yourself being there!

Getting Started

To get started, download the starter project using the Download Materials button at the top or bottom of this tutorial. The project contains a GeoJSON file and some image assets, but no maps yet!

Open Main.storyboard and, from the Object library, drag a Map Kit View into the middle of the scene. Constrain the Map View to the super view (not the Safe Area), setting 0 on all edges, so it stretches throughout the Safe Area of notched devices.

Build and run. You now have a fully zoomable and panable map showing the continent of your current location using Apple Maps!

Map view of Australia, Indonesia and Papua New Guinea.

So far, so good, eh?

But you don’t want to start the map looking at the entire world, unless you’re a super-villain, cue evil laugh… You want to zoom into a particular area. And to do that, you need to get coding!

Open ViewController.swift and add the following below the import UIKit statement:

import MapKit

Next, you’ll need an outlet for the MKMapView in ViewController.swift.

Add the following outlet code immediately before viewDidLoad():

@IBOutlet private var mapView: MKMapView!

Then, go to Main.storyboard and link the Map View to your new outlet:

Connecting the Map View from  Storyboard to your Outlet

Setting the Visible Area

Go back to ViewController.swift, find viewDidLoad() and add the following to the end of the method:

// Set initial location in Honolulu
let initialLocation = CLLocation(latitude: 21.282778, longitude: -157.829444)

You’ll use this to set the starting coordinates of the map view to a point in Honolulu.

When telling the map what to display, giving latitude and longitude is enough to center the map. But, you must also specify the rectangular region to display to get a correct zoom level.

Add the following private extension at the end of ViewController.swift:

private extension MKMapView {
  func centerToLocation(
    _ location: CLLocation, 
    regionRadius: CLLocationDistance = 1000
  ) {
    let coordinateRegion = MKCoordinateRegion(
      center: location.coordinate,
      latitudinalMeters: regionRadius,
      longitudinalMeters: regionRadius)
    setRegion(coordinateRegion, animated: true)
  }
}

The location argument is the center point. The region will have north-south and east-west spans based on a distance of regionRadius, which has a default of 1000 meters, a little more than half a mile, which works well for plotting the public artwork data in the GeoJSON file.

setRegion(_:animated:) tells MKMapView to display the region represented by MKCoordinateRegion. The map view automatically transitions the current view to the desired region with a neat zoom animation, with no extra code required!

Back in viewDidLoad(), add the following line to the end of the method:

mapView.centerToLocation(initialLocation)

This calls the helper method to zoom into initialLocation on startup.

Build and run. You’ll find yourself in the heart of Waikiki. Aloha! :]

Map of downtown Waikiki.

Constraining the Camera

So far, you’ve been able to go anywhere you want on the map, but we’re only interested in the island of Oahu. You’ve also been able to pinch in to zoom the map so far that the island is only a few pixels! MapKit is capable of constraining the user to pan and zoom the map over a specified area.

Note: To zoom in the Simulator, hold Option and drag in the map view.

Once again in viewDidLoad(), add the following lines to the end of the method:

    let oahuCenter = CLLocation(latitude: 21.4765, longitude: -157.9647)
    let region = MKCoordinateRegion(
      center: oahuCenter.coordinate,
      latitudinalMeters: 50000,
      longitudinalMeters: 60000)
    mapView.setCameraBoundary(
      MKMapView.CameraBoundary(coordinateRegion: region),
      animated: true)
    
    let zoomRange = MKMapView.CameraZoomRange(maxCenterCoordinateDistance: 200000)
    mapView.setCameraZoomRange(zoomRange, animated: true)

Build and run. Now when you zoom out, you can’t make Oahu as small as before. You can only pan the map view to see the northern, southern, eastern and westernmost edges of the island.

MapKit uses an internal camera to determine where the point of view for the map is, how expansive the field of view is and to animate view movement. When you specify a camera boundary with a center and a region rectangle, the camera center always stays within this region.

If the user tries to pan further out of the region, the view doesn’t scroll any further. It keeps them focused on the area you want them to see. A region size of 60,000 meters wide by 50,000 meters high keeps Oahu nicely constrained within the map view.

The MapKit view camera keeps track of its distance from the view center when zooming in and out. Setting the camera zoom range maximum center distance constraint limits how far the view zooms out and how tiny the island of Oahu becomes. This is even more helpful when adding points of interest to the map, which is the next step!

Obtaining Public Art Data

The next step is to plot interesting data around the current location. But where in the world can you get such stuff?

Well, it depends on your current location. Honolulu, like many cities, has an Open Data Portal to improve public access to government data.

One convenient feature of Honolulu’s data portal is the ability to export the data set in GeoJSON format — a flavor of JSON that’s used to represent geospatial features along with their metadata. One of MapKit’s recent features makes it super-easy to use GeoJSON data in your app, as you’ll soon see.

Note: After you finish this tutorial, look around to see if a nearby city has another dataset in GeoJSON format you can use. Once you see how easy it is, you may find it interesting plotting different datasets together on the same map.

For this tutorial, you’ll use the Honolulu Public Art dataset. To keep things simple, I’ve already exported this data from the portal and included it in the starter project, nicely formatted for readability, of course. It’s the least I could do.

To get a feeling for the items in this dataset, open PublicArt.geojson in the Xcode editor. At the top level you’ll see:

{
  "type": "FeatureCollection",
  "features": [ ... ]
}

The value for the key features is an array of GeoJSON objects of the type Feature. Each one of these objects contains some standard keys, but also a properties dictionary with some custom fields created by the data portal. The geometry key is where you’ll find the coordinates of the feature.

Have a look at the first one:

{
  "type":"Feature",
  "properties":{
    "location":"Lester McCoy Pavilion",
    "latitude":"21.290824",
    "description":"...",
    "thumb":null,
    "credit":"Funded by the Works Progress Administration",
    "objectid":"1930.01.01",
    "creator":"Robert Lee Eskridge",
    "longitude":"-157.85131",
    "imagefile":"http://....JPG",
    "date":"1935",
    "discipline":"Mural",
    "title":"The Makahiki Festival - The Makai Mural",
    "access":"Limited"
  },
  "geometry":{
    "type":"Point",
    "coordinates":[-157.85131,21.290824]
  }
}