MapKit Tutorial: Getting Started

Audrey Tam
Plot Honolulu public artwork data using MapKit!

Plot Honolulu public artwork data using MapKit!

Code update September 22, 2016: Updated the final project to Swift 3.

Update April 10, 2015: Updated for Xcode 6.3 / Swift 1.2.

Update notes: Audrey Tam updated this tutorial to Swift and iOS 8. Original post by Ray Wenderlich. Ray’s original tutorial queried and retrieved data from the Baltimore web service but the code broke when the web service made minor changes, so this update uses a static JSON file downloaded from the Honolulu data portal.

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

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!

In this tutorial, you’re going to make an app that zooms into a location in Honolulu, and you’ll plot one of the artworks on the map. Just for fun, you’ll implement the pin’s callout detail button to launch the Maps app, with driving/walking directions to the artwork. Your app will then parse a JSON file from a Honolulu data portal, to extract the public artwork objects, 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, parse government data that uses the Socrata Framework, create custom map annotations, and more!

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

Without further ado, let’s get mapping!

Getting Started

In Xcode, go to File\New\New Project, select iOS\Application\Single View Application, and click Next. Then type HonoluluArt as the project name. Set Language to Swift and select iPhone for the Devices option. Make sure that Use Core Data is unchecked, then click Next, and choose a directory to save your project in to finish.

Open Main.storyboard and, from the Object library, drag a MapKit View onto the scene, letting it expand to fill the screen.

To set constraints to pin all the edges to the superview, so that your layout works for all the different screen sizes, click on the view controller icon then select Resolve Autolayout Issues\Reset to Suggested Contstraints from the lower All Views in View Controller section:

storyboardConstraints

Before you can run your code, you need to create an outlet for the map view in ViewController.swift, or else it will crash on startup!

The outlet’s type will be MKMapView, so you first need to add the MapKit framework to your project.

Open the Assistant editor: it should display ViewController.swift. Just below the import UIKit statement, add this line:

import MapKit

To create the outlet, click the Map View in Main.storyboard and control-drag from it into the space just inside the ViewController class definition: Xcode should prompt you to Insert Outlet or Outlet Collection. Release the drag and, in the pop-up window, name the outlet mapView:

storyboardOutlet

Xcode adds a mapView property to the ViewController class – you’ll use this to control what the map view displays.

While you’re here, delete the didReceiveMemoryWarning method; you won’t be needing it.

Build and run your project, and you’ll have a fully zoomable and pannable map showing the continent of your current location, using Apple Maps!

run1

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

Setting Visible Area

In 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 the starting coordinates of the map view to a point in Honolulu.

When you are trying to tell the map what to display, you can’t just give a latitude and longitude. That’s enough to center the map, but you need to specify the rectangular region to display to get a correct zoom level too.

Add the following constant and helper method to the class:

let regionRadius: CLLocationDistance = 1000
func centerMapOnLocation(location: CLLocation) {
  let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, 
    regionRadius * 2.0, regionRadius * 2.0)
  mapView.setRegion(coordinateRegion, animated: true)
}

The location argument is the center point. The region will be have north-south and east-west spans based on a distance of regionRadius – you set this to 1000 meters (1 kilometer), which is a little more than half a mile. You then use regionRadius * 2.0 here, because that works well for plotting the public artwork data in the JSON file.

setRegion tells 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!

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

centerMapOnLocation(initialLocation)

This will call the helper method to zoom into initialLocation on startup.

Build and run the app, and now it should zoom in to the heart of Waikiki :]

run2

Obtaining Public Artworks Data

The next step is to plot some interesting data around the current location. But where in the heck can we 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. Like many cities, Honolulu’s data portal is “Powered by Socrata“, an open data framework which provides a rich set of developer tools for accessing Socrata-based data. After you finish this tutorial, maybe look around to see if a nearby city has an alternate dataset you can use?

For this tutorial, you’ll be using the Honolulu Public Art dataset. To keep things simple, I have already downloaded this data from the portal for you – download the HonoluluArtResources.zip file here. Unzip it to find two files: PublicArt.json and JSON.swift. You’ll use JSON.swift later in this tutorial, to parse PublicArt.json.

When you have the PublicArt.json file, drag it into your HonoluluArt\Supporting Files group, make sure Destination: Copy items if needed and Add to targets: HonoluluArt are selected, and click Finish.

To get a feeling for the items in this dataset, open PublicArt.json in the Xcode editor and scroll down to line 1180 (or use ⌘ + L for Jump to Line), which begins with "data" followed by an array of arrays – one array for each artwork. For this tutorial, you’ll use only a few properties from each array: the artwork’s location name, discipline, title, latitude and longitude. For example, for the first data item:

  • location name: Lester McCoy Pavilion
  • discipline: Mural
  • title: The Makahiki Festival – The Makai Mural
  • latitude: 21.290824
  • longitude: -157.85131

Later in this tutorial, you’ll parse this dataset to create an array of Artworks but first, to jump straight into the MapKit fun, you’ll just plot one of the artworks on the map.

Showing an Artwork on the Map

In PublicArt.json, scroll down further to item 55 at line 1233 (or use ⌘ + L for Jump to Line) – it’s a bronze statue of King David Kalakaua in Waikiki Gateway Park – ah, can you hear the tradewinds sighing through the palm trees?

KingKalakaua

Photo of King David Kalakaua statue, by Wally Gobetz

The properties for this item are:

  • location name: Waikiki Gateway Park
  • discipline: Sculpture
  • title: King David Kalakaua
  • latitude: 21.283921
  • longitude: -157.831661

To show this on the map view, you must create a map annotation. In the context of MapKit, annotations are small pieces of information tied to a particular location and are most often represented as the little pins that show up in the Maps app.

Creating your own annotations is easy. All you need is a class that conforms to MKAnnotation, add the annotation to the map, and inform the map how the annotation should be displayed.

Begin with step 1: create an Artwork class in a new Swift file. To specify the new file’s position in the Project Navigator, select ViewController.swift, so the new file will appear below this. Next, go to File\New\New File, choose iOS\Source\Swift File, and click Next. Set the Save As field to Artwork.swift and click Create.

Open Artwork.swift in the editor and add the following, below import Foundation:

import MapKit

class Artwork: NSObject, MKAnnotation {
  let title: String
  let locationName: String
  let discipline: String
  let coordinate: CLLocationCoordinate2D
  
  init(title: String, locationName: String, discipline: String, coordinate: CLLocationCoordinate2D) {
    self.title = title
    self.locationName = locationName
    self.discipline = discipline
    self.coordinate = coordinate
    
    super.init()
  }
  
  var subtitle: String {
    return locationName
  }
}

This is a plain old NSObject with a special initializer. Note it marks itself as implementing the MKAnnotation protocol. This means that the coordinate property is required. If you want the annotation view to display a title and subtitle when the user selects a pin, the class also needs properties named title and subtitle.

It’s perfectly sensible for the Artwork class to have stored properties named title and coordinate but none of the PublicArt.json properties maps naturally to the idea of “subtitle”. To conform to the MKAnnotation protocol, subtitle is a computed property that returns locationName.

OK, so the title, locationName and coordinate properties will be used for the MKAnnotation object, but what’s the discipline property for? You’ll find out later in this tutorial ;]

On to step 2 – add an instance of the Artwork class for every artwork you want to plot. You’re adding only one artwork to the map so add the following lines to the end of viewDidLoad in ViewController.swift:

// show artwork on map
let artwork = Artwork(title: "King David Kalakaua",
  locationName: "Waikiki Gateway Park", 
  discipline: "Sculpture",
  coordinate: CLLocationCoordinate2D(latitude: 21.283921, longitude: -157.831661))

mapView.addAnnotation(artwork)

This creates a new Artwork object and adds it as an annotation to the map view. The MKMapView class also has an addAnnotations method, which you’ll use later in this tutorial, when you have an array of annotations to add to the map view.

OK, on to the third and final step: providing the map with the information it needs to display the annotation! To do so, the map view will call its viewForAnnotation delegate method. Your job in this delegate method is to return an instance of MKPinAnnotationView to present as a visual indicator of the annotation.

In this case, your ViewController will be the delegate for the map view. To avoid clutter and improve readability, you’ll create an extension of ViewController in a separate file.

Create a new Swift file: go to File\New\New File, choose iOS\Source\Swift File, and click Next. Set the Save As field to VCMapView.swift and click Create. Then add the following, below import Foundation:

import MapKit

extension ViewController: MKMapViewDelegate {
  
  // 1
  func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
    if let annotation = annotation as? Artwork {
      let identifier = "pin"
      var view: MKPinAnnotationView
      if let dequeuedView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)
        as? MKPinAnnotationView { // 2
        dequeuedView.annotation = annotation
        view = dequeuedView
      } else {
        // 3
        view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
        view.canShowCallout = true
        view.calloutOffset = CGPoint(x: -5, y: 5)
        view.rightCalloutAccessoryView = UIButton.buttonWithType(.DetailDisclosure) as! UIView
      }
      return view
    }
    return nil
  }
}

This code isn’t too complicated, but here’s a quick breakdown:

  1. mapView(_:viewForAnnotation:) is the method that gets called for every annotation you add to the map (kind of like tableView(_:cellForRowAtIndexPath:) when working with table views), to return the view for each annotation.
  2. Also similarly to tableView(_:cellForRowAtIndexPath:), map views are set up to reuse annotation views when some are no longer visible. So the code first checks to see if a reusable annotation view is available before creating a new one.
  3. Here you use the plain vanilla MKAnnotationView class if an annotation view could not be dequeued. It uses the title and subtitle properties of your Artwork class to determine what to show in the callout – the little bubble that pops up when the user taps on the pin.

Note: One extra thing to point out about this, suggested by Kalgar, when you dequeue a reusable annotation, you give it an identifier. If you have multiple styles of annotations, be sure to have a unique identifier for each one, otherwise you might mistakenly dequeue an identifier of a different type, and have unexpected behavior in your app. It’s basically the same idea behind a cell identifier in tableView(_:cellForRowAtIndexPath:).

All that’s left is setting ViewController as the delegate of the map view. You can do this in Main.storyboard, but I prefer to do it in code, where it’s more visible. In ViewController.swift, add this line to viewDidLoad, before the statement that creates artwork:

mapView.delegate = self

And that’s it! Build and run your project, and now you should see where King David Kalakaua’s statue is, at the gateway to Waikiki!

run3

mapView(_:viewForAnnotation:) configures the callout to include a detail disclosure info button on the right side but tapping that button doesn’t do anything yet. You could implement it to show an alert with more info, or to open a detail view controller. In Swift By Tutorials, the TreasureHunt app in Chapter 3 shows an alert, and the CafeHunter app in Chapter 8 opens a detail view controller.

Here’s a neat third option: when the user taps the info button, your app will launch the Maps app, complete with driving/walking directions to get from the simulated user location to the artwork!

Launching the Maps App

To provide this great user experience, open Artwork.swift and add this import statement, below the other two import statements:

import AddressBook

This adds the AddressBook framework. What does the address book framework have to do with maps, you might ask? Well, it contains some dictionary key constants such as kABPersonAddressStreetKey for when you need to set the address or city or state fields of a location.

Next, add the following helper method to the class:

// annotation callout info button opens this mapItem in Maps app
func mapItem() -> MKMapItem {
  let addressDictionary = [String(kABPersonAddressStreetKey): subtitle]
  let placemark = MKPlacemark(coordinate: coordinate, addressDictionary: addressDictionary)
  
  let mapItem = MKMapItem(placemark: placemark)
  mapItem.name = title
  
  return mapItem
}

Here you create an MKMapItem from an MKPlacemark. The Maps app is able to read this MKMapItem and display the right thing.

Next, you have to tell MapKit what to do when the callout button is tapped. To do so, open VCMapView.swift and add this method to the MKMapViewDelegate extension:

func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, 
    calloutAccessoryControlTapped control: UIControl!) {
  let location = view.annotation as! Artwork
  let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
  location.mapItem().openInMapsWithLaunchOptions(launchOptions)
}

When the user taps a map annotation pin, the callout shows an info button. If the user taps this info button, the mapView(_:annotationView:calloutAccessoryControlTapped:) method is called.

In this method, you grab the Artwork object that this tap refers to and then launch the Maps app by creating an associated MKMapItem and calling openInMapsWithLaunchOptions on the map item.

Notice you’re passing a dictionary to this method. This allows you to specify a few different options; here the DirectionModeKeys is set to Driving. This will make the Maps app try to show driving directions from the user’s current location to this pin. Neat!

I suggest you take a look at the various different options you can pass in the launch options dictionary. Also take a look at the MKMapItem class method that allows you to pass multiple MKMapItem objects at the same time.

Before you build and run, it is a good idea to simulate your location to Honolulu. In Xcode, go to Product\Scheme\Edit Scheme… and select Run from the left menu, then select the Options tab. Check Core Location: Allow Location Simulation and select Honolulu, HI, USA as the Default Location. Then click the Close button:

defaultUserLocation

Build and run the app and you’ll see the map zoom in on Waikiki, as before. Tap on the pin, then tap the info button in the callout and watch it launch the Maps app to show the statue’s location, with driving directions to it:

run4b

This calls for a celebration – treat yourself to your favorite tropical drink!

Note: To return to your HonoluluArt app, hold down the ⌘ key and press H twice to show the active apps – just like pressing the iPhone’s Home button twice!

Parsing JSON Data into Artwork Objects

Now that you know how to show one artwork on the map and how to launch the Maps app from the pin’s callout info button, it’s time to parse the dataset into an array of Artwork objects. Then you can search this array for objects that are in the current map region, and show them on the map.

First, find the JSON.swift file that was in the resources zip file along with PublicArt.json. JSON.swift contains a wonderful enumeration that makes JSON parsing a piece of cake. You can read all about it in Chapter 6 of Swift By Tutorials but basically, it provides a case for each type of JSON value, and a library of computed properties to extract the various values.

Add JSON.swift to the HonoluluArt group in the Project Navigator, then add this method to Artwork.swift, below the initializer:

class func fromJSON(json: [JSONValue]) -> Artwork? {
  // 1
  var title: String
  if let titleOrNil = json[16].string {
    title = titleOrNil
  } else {
    title = ""
  }
  let locationName = json[12].string
  let discipline = json[15].string

  // 2
  let latitude = (json[18].string! as NSString).doubleValue
  let longitude = (json[19].string! as NSString).doubleValue
  let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)

  // 3
  return Artwork(title: title, locationName: locationName!, discipline: discipline!, coordinate: coordinate)
}

Just a few notes about this code:

  1. fromJSON‘s json argument will be one of the arrays that represent an artwork – an array of JSONValue objects. If you count through an array’s elements, you’ll see that the title, locationName etc. are at the indexes specified in this method. The title for some of the artworks is null so you test for this when setting the title value.
  2. This converts the string latitude and longitudes to NSString objects so you can then use the handy doubleValue to convert them to doubles.
  3. The computed string property from JSON.swift returns an optional string for locationName and discipline, which must be implicitly unwrapped when passing them to the Artwork initializer

In other words, the fromJSON method converts an array like this:

[ 55, "8492E480-43E9-4683-927F-0E82F3E1A024", 55, 1340413921, "436621", 1340413921, "436621", "{\n}", "Sean Browne",
"Gift of the Oahu Kanyaku Imin Centennial Committee", "1989", "Large than life-size bronze figure of King David Kalakaua
mounted on a granite pedestal. Located at Waikiki Gateway Park.", "Waikiki Gateway Park", 
"http://hiculturearts.pastperfect-online.com/34250images/002/199103-3.JPG", "1991.03", "Sculpture", "King David 
Kalakaua", "Full", "21.283921", "-157.831661", [ null, "21.283921", "-157.831661", null, false ], null ]

into an Artwork object like the one you created before:

  • locationName: “Waikiki Gateway Park”
  • discipline: “Sculpture”
  • title: “King David Kalakaua”
  • coordinate with latitude: 21.283921 longitude: -157.831661

To use fromJSON(_:), open ViewController.swift and add the following property to the class – an array to hold the Artwork objects from the JSON file:

var artworks = [Artwork]()

Next, add the following helper method to the class:

func loadInitialData() {
  // 1
  let fileName = NSBundle.mainBundle().pathForResource("PublicArt", ofType: "json");
  var readError : NSError?
  var data: NSData = NSData(contentsOfFile: fileName!, options: NSDataReadingOptions(0),
    error: &readError)!

  // 2
  var error: NSError?
  let jsonObject: AnyObject! = NSJSONSerialization.JSONObjectWithData(data, 
    options: NSJSONReadingOptions(0), error: &error)

  // 3
  if let jsonObject = jsonObject as? [String: AnyObject] where error == nil,
  // 4
  let jsonData = JSONValue.fromObject(jsonObject)?["data"]?.array {
    for artworkJSON in jsonData {
      if let artworkJSON = artworkJSON.array,
      // 5
      artwork = Artwork.fromJSON(artworkJSON) {
        artworks.append(artwork)
      }
    }
  }
}

Here’s a run-down of what you’re doing in this code:

  1. Read the PublicArt.json file into an NSData object
  2. Use NSJSONSerialization to obtain a JSON object
  3. Check that the JSON object is a dictionary where the keys are Strings and the values can be AnyObject
  4. You’re only interested in the JSON object whose key is "data" and you loop through that array of arrays, checking that each element is an array
  5. Pass each artwork’s array to the fromJSON method that you just added to the Artwork class. If it returns a valid Artwork object, you append it to the artworks array.

Plotting the Artworks

You now have an array of all the public artworks in the dataset, which you need to add to the map.

Under the lines in viewDidLoad that create initialLocation and center the map view there, add calls to loadInitialData() and mapView.addAnnotations(artworks):

loadInitialData()
mapView.addAnnotations(artworks)

Note: Be sure to use (plural) addAnnotations, not (singular) addAnnotation!

Comment out or delete the lines that create the single “King David Kalakaua” map annotation – you don’t need them, now that loadInitialData creates the artworks array:

//    let artwork = Artwork(title: "King David Kalakaua", locationName: "Waikiki Gateway Park",
//      discipline: "Sculpture", coordinate: CLLocationCoordinate2D(latitude: 21.283921, longitude: -157.831661))
//    mapView.addAnnotation(artwork)

Build and run your app and check out all the pins!

run5a

Move the map around to see other pins appear:

run5b

Tap a pin to open its callout bubble, then tap its info button to launch the Maps app – yes, everything you did with the King Kalakaua statue works with all these new artworks!

Note: Thanks to Dave Mark for pointing out that Apple recommends adding all the annotations right away, whether or not they’re visible in the map region – when you move the map, it automatically displays the visible annotations.

And that’s it! You’ve built an app that parses a JSON file into an array of artworks, then displays them as annotation pins, with a callout info button that launches the Maps app – celebrate with a hula dance around your desk :]

But wait, there’s one little bit of bling that I saved for last…

Color-Coded Pins

Remember the discipline property in the Artwork class? Its values are things like “Sculpture” and “Mural” – in fact, the most numerous disciplines are Sculpture, Plaque, Mural and Monument. It’s easy to color-code the pins so that Sculptures and Plaques have red pins and Murals and Monuments have purple pins, with green pins for all the other disciplines.

In Artwork.swift, add this method:

// pinColor for disciplines: Sculpture, Plaque, Mural, Monument, other
func pinColor() -> MKPinAnnotationColor  {
  switch discipline {
  case "Sculpture", "Plaque":
    return .Red
  case "Mural", "Monument":
    return .Purple
  default:
    return .Green
  }
}

Then, in VCMapView.swift, specify the pinColor in mapView(_:viewForAnnotation:) by adding this line after the else closure:

view.pinColor = annotation.pinColor()

The color needs to be reset every time the view is being reused, since the pin view could previously have been of a different discipline.

Build and run your app to see the different colored pins:

run7

You’re restricted to three pin colors because MKPinAnnotationColor only has those ones defined. Another option for customization is to use images instead of colors. You could replace the pinColor method with a pinImage method in Artwork.swift and set view.image instead of view.pinColor in ViewController.swift.

Bonus Topic: User Location Authorization

This app doesn’t need to ask the user for authorization to access their location but it’s something you might want to include in your other MapKit-based apps. Apple’s phrase is “to use location services” – as of iOS 8, this requires some extra steps, beyond checking a checkbox in the map view’s Attributes pane.

In ViewController.swift, add the following lines:

// MARK: - location manager to authorize user location for Maps app
var locationManager = CLLocationManager()
func checkLocationAuthorizationStatus() {
  if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse {
    mapView.showsUserLocation = true
  } else {
    locationManager.requestWhenInUseAuthorization()
  }
}

override func viewDidAppear(animated: Bool) {
  super.viewDidAppear(animated)
  checkLocationAuthorizationStatus()
}

This code creates a CLLocationManager object, which keeps track of your app’s authorization status for accessing the user’s location. The checkLocationAuthorizationStatus method checks your app’s status: if your app is authorized, then it effectively checks the map view’s Shows-User-Location checkbox; otherwise, it gets the locationManager to request authorization from the user.

Note: The locationManager can make two kinds of authorization requests: requestWhenInUseAuthorization or requestAlwaysAuthorization. The first lets your app use location services while it is in the foreground; the second authorizes your app whenever it is running. Apple’s documentation discourages the use of “Always”:

Requesting “Always” authorization is discouraged because of the potential negative impacts to user privacy. You should request this level of authorization only when doing so offers a genuine benefit to the user.

Info.plist item: important but easy to overlook!

There’s just one more authorization-related task you need to do – if you don’t, your app won’t crash but the locationManager’s request won’t appear. To get the request to work, you must add an item named NSLocationWhenInUseUsageDescription to your app’s Information Property List, and set its Type to String and its Value to a message that explains to the user why they should allow your app to access their location.

Open Info.plist and, if it’s closed, open the Information Property List. Hover your cursor over the up-down arrows, or click on any item in the list, to display the + and – symbols, then click the + symbol to create a new item. Name it NSLocationWhenInUseUsageDescription, check that its Type is String, then set its Value to something like To show you cool things nearby:

Infoplist

With a usage description like that, who wouldn’t allow access? ;]

Where To Go From Here?

Here is the final project with all of the code you’ve developed in this tutorial.

Note: Here is the Swift 3 version of the project.

Now you know the basics of using MapKit, but there’s a lot more you can do from here, including geocoding, adding custom map overlays, and more. A great place to go to for additional information is Apple’s Location Awareness Programming Guide.

To take this app further you may want to look into the MKMapItem class method I hinted at for opening the Maps app with multiple items. Perhaps add a button to the toolbar that opens the Maps app with all of the artworks currently shown. Also, why not take a look at the other launch dictionary options to control what happens when Maps opens?

If you want to decorate or customize the map provided by Apple with your own annotations and images, look at Overlay Views with MapKit and Swift Tutorial – it starts by setting up a map view, but there’s also an advanced starter project, if you want to dive right into the overlay image code.

If you want to learn more about MapKit features in iOS 6 and iOS 7, including registering your app as a routing provider, you should check out our books iOS 6 By Tutorials and iOS 7 By Tutorials. Fully updated for iOS 8 and Xcode 6, each book contains a chapter on MapKit. The iOS 6 chapter covers how you can launch Maps with various options, and how you can register your own app as a routing provider to give directions to users! The iOS 7 chapter covers Flyover, overlays, and the Directions, Snapshots and Cameras APIs.

If you have any questions as you use MapKit in your apps, hints for other MapKit users, or are interested in using government data in your apps, please join in the forum discussion below!

Audrey Tam

Audrey Tam retired at the end of 2012 from a 25-year career as a computer science academic. Her teaching included Pascal, C/C++, Java, Java web services, web app development in php and mysql, user interface design and evaluation, and iOS programming. Before moving to Australia, she worked on Fortran and PL/1 simulation software at IBM's development lab in Silicon Valley. Audrey now teaches short courses in iOS app development to non-programmers, and attends nearly all Melbourne Cocoaheads monthly meetings.

Other Items of Interest

Save time.
Learn more with our video courses.

raywenderlich.com Weekly

Sign up to receive the latest tutorials from raywenderlich.com each week, and receive a free epic-length tutorial as a bonus!

Advertise with Us!

PragmaConf 2016 Come check out Alt U

Our Books

Our Team

Video Team

... 20 total!

Swift Team

... 15 total!

iOS Team

... 42 total!

Android Team

... 16 total!

macOS Team

... 11 total!

Unity Team

... 11 total!

Articles Team

... 12 total!

Resident Authors Team

... 15 total!