Introduction to MapKit in iOS 6 Tutorial

A tutorial that shows you how you can use MapKit in your iOS apps to show maps, drop pins, look up addresses, and more! By Matt Galloway.

Leave a rating/review
Save for later
Share

Plot Baltimore arrests data using MapKit!

Plot Baltimore crime data using MapKit!

Plot Baltimore arrests data using MapKit!

Note from Ray: This is the sixth iOS 6 tutorial in the iOS 6 Feast! In this tutorial, we’re updating one of our older tutorials to iOS 6 so it’s fully up-to-date with the latest features like the new Apple Maps in iOS 6 and related new iOS 6 APIs.

Parts of this tutorial come from Matt Galloway‘s “What’s New with MapKit chapter” in our new book iOS 6 by Tutorials, although the book is about a different app (a subway route finder!) and takes things MUCH further than this simple example, such as registering your app as a routing provider. Enjoy!

Update 9/9/12: Fully updated for iOS 6 by Matt Galloway.

Update 3/19/12: Fully updated for iOS 5 by Malek Trabelsi.

3/23/11: Original post by Ray Wenderlich.

MapKit is a really neat API available on the iPhone that makes it easy to display maps, jump to coordinates, plot locations, and even draw routes and other shapes on top.

I’m writing this tutorial because about a month ago I attended a neat event in Baltimore called Civic Hack Day where I played around with MapKit to display some public data such as place locations, crime data, arrests and bus routes. It was kind of fun so thought others might be interested to learn how it works – and maybe use a similar technique with data from your own hometown!

In this tutorial, we’re going to make an app that zooms into a particularly cool location in Baltimore. The app will then query a Baltimore web service to pull back the recent arrests around that area, and plot them on the map.

In the process, you’ll learn how to add a MapKit map to your app, zoom to a particular location, query and retrieve government data available via the Socrata API, create custom map annotations, and more!

This tutorial assumes some familiarity with Objective-C and iOS programming. If you are a complete beginner, you may wish to check out some of the other tutorials on this site.

This tutorial uses Xcode 4.5 with iOS 6 features such as Objective-C literals and the new mapping engine developed directly by Apple. It also uses iOS 5 features such as Storyboard, ARC. You really are living at the cutting edge with us!

Without further ado, let’s get mapping!

Getting Started

In Xcode 4.5, go to File\New\New Project, select iOS\Application\Single View Application, and click Next. Then type ArrestsPlotter as the project name. Make sure Use Storyboard and Use Automatic Reference Counting options are checked. Also make sure iPhone is selected for the Devices option. Then click Next, and choose a directory to save your project in to finish.

Click on MainStoryboard.storyboard to bring up Interface Builder. Then bring up the Object library by selecting the third tab in the View toolbar (Utilities) and selecting the third tab in the library toolbar (Object library), as shown in the screenshot below.

Object Library in Xcode 4.2

From the Object library, drag a toolbar to the bottom of the screen, and a Map View to the middle of the screen, and rename the toolbar button to read “Refresh”, as shown in the screenshot below. It’s important to add the toolbar first and then the map, because if you do it that way round you’ll notice that the map automagically takes up the remaining space. It’s as if Xcode is reading your mind!

View Layout with MapKit

Next, click on the map view you added to the middle of the screen, and click on the fourth tab in the inspector toolbar to switch to the Attributes inspector. Click the checkbox for Shows User Location, as shown below.

Show User Location on Map View

Almost done, but before you can run your code you need to add the MapKit framework to your project (or else it will crash on startup!)

To do this in Xcode 4.5, click on the name of your project in the Groups & Files tree, select the ArrestsPlotter target, and switch to the Build Phases tab. Open the Link Binary With Libraries section, click the Plus button, find the entry for MapKit.framework, and click Add.

At this point your screen should look like the screenshot below:

Adding a Framework with Xcode 4

Now you should be able to compile and run your project, and have a fully zoomable-and-pannable map showing your current location (or Cupertino if you’re using the Simulator), using Google Maps!

So far so good, eh? But we don’t want the map to start looking at the entire world – we want to take a look at a particular area!

As an aside, you might want to at this point experiment with Xcode’s simulate location feature. You’ll notice that the app currently thinks you’re in Cupertino. That’s all well and good, but maybe you want to pretend you’re somewhere else far far away from 1 Infinite Loop. Although I’m not sure why you wouldn’t want to pretend you were there… Anyway, you can simulate your location by clicking the location indicator icon at the bottom of the main Xcode panel whilst the app is running. From there you can select a location. See the screenshot below for an example.

Setting Visible Area

First, we need to connect the Map View you created in Interface Builder to an instance variable in your view controller. We could do this the old fashioned way (create an instance variable and property, and connect with Interface Builder by right clicking and drawing lines from the outlet to the map view), but there’s an even easier way in Xcode!

To do this, select MainStoryboard.storyboard again, and make sure that the assistant editor is selected (the second tab in the Editor tab group). I like to have mine show up at the bottom – you can set the position with View\Assistant Layout\Assistant Editors at Bottom.

In the toolbar at the top of the Assistant Editor, make sure Automatic is selected, and that it is set to display ViewController.h. If it’s not, click on Automatic, on the drop down list, choose Manual and look for ViewController.h like shown in the screenshot below.

Show File With Assistant Editor

Now, control-drag from the Map View down to your header file, right in the middle of the @interface declaration, and before the @end.

A popup will appear. Set the connection type to Outlet, the name to mapView, keep the Type as MKMapView, the Storage as Weak, and click Connect. It will automatically make a property for your map view and hook it up for you!

This calls for a celebration – 3 w00ts (and one rage) for Xcode 4!

Xcode 4 Rage Comic

(If you don’t get this, check out the Introduction to In-App Purchases tutorial for more details on rage comics :])

Ahem – back to work! Open ViewController.m, and add the following underneath the #imports and before the @implementation:

#define METERS_PER_MILE 1609.344

This simply adds a constant for meters per mile which you’ll be using later. Now implement viewWillAppear to zoom in to an initial location on startup:

- (void)viewWillAppear:(BOOL)animated {  
    // 1
    CLLocationCoordinate2D zoomLocation;
    zoomLocation.latitude = 39.281516;
    zoomLocation.longitude= -76.580806;
    
    // 2
    MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE);
    
    // 3
    [_mapView setRegion:viewRegion animated:YES];
}

There’s a lot of new stuff here, so let’s go over it bit by bit.

  1. Picks out the location to zoom in. Here we choose the location in Baltimore where I initially wrote this app, which is a good choice for the BPD Arrests API we’ll be using later on in this tutorial.
  2. When you are trying to tell the map what to display, you can’t just give a lat/long – you need to specify the box (or region) to display. So this uses a helper function to make a region around a center point (the user’s location) and a given width/height. We use half a mile here, because that works well for plotting arrests data.
  3. Finally, tells the mapView to display the region. The map view automatically transitions the current view to the desired region with a neat zoom animation with no extra code required!

Compile and run the app, and now it should zoom in to Baltimore area :]