# MapKit Tutorial: Getting Started

**URL:** <https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355>\
**Category:** 🎓 Courses & Articles\
**Created:** [March 4, 2016, 10:40am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355 "2016-03-04T10:40:20Z")\
**Posts on this page:** 20\
**Page:** 7

<div class="post-metadata">

**Author:** ![audrey](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/audrey/32/111607_2.png) [@audrey](https://forums.kodeco.com/u/audrey)\
**Post date:** [January 5, 2017, 9:03pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/124 "2017-01-05T21:03:22Z")

</div>

Look at this tutorial: [https://www.raywenderlich.com/110054/routing-mapkit-core-location](https://www.raywenderlich.com/110054/routing-mapkit-core-location)

Scroll about halfway down, to “Calculating Route…” with MapKit. It’s older Swift, but Xcode will help you update it, or check the documentation for `MKDirectionsRequest` and `MKRoute`.

---

<div class="post-metadata">

**Author:** ![drago](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/drago/32/53586_2.png) [@drago](https://forums.kodeco.com/u/drago)\
**Post date:** [January 5, 2017, 11:06pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/125 "2017-01-05T23:06:37Z")

</div>

Oh sorry, you misunderstood me, I don’t wanna make route like in this example, I make route like in your example, and this great, but I want to “func mapItem()” works when user tapped not on information button and the my button

---

<div class="post-metadata">

**Author:** ![audrey](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/audrey/32/111607_2.png) [@audrey](https://forums.kodeco.com/u/audrey)\
**Post date:** [January 6, 2017, 1:14am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/126 "2017-01-06T01:14:08Z")

</div>

put the code from `calloutAccessoryControlTapped` into your button’s action:

```
let location = view.annotation as! Artwork
  let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
  location.mapItem().openInMapsWithLaunchOptions(launchOptions)

```

your view controller needs to keep track of the annotation view that’s the route destination, so the action uses that as `view` in the code above

---

<div class="post-metadata">

**Author:** ![drago](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/drago/32/53586_2.png) [@drago](https://forums.kodeco.com/u/drago)\
**Post date:** [January 6, 2017, 12:51pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/127 "2017-01-06T12:51:26Z")

</div>

Can you please show example, what i need write in code to create this button?

---

<div class="post-metadata">

**Author:** ![audrey](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/audrey/32/111607_2.png) [@audrey](https://forums.kodeco.com/u/audrey)\
**Post date:** [January 6, 2017, 10:58pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/128 "2017-01-06T22:58:53Z")

</div>

for example, using the single artwork “King David Kalakaua”, at the end of `viewDidLoad`:

declare `artwork` as a property of the view controller:

`var artwork: Artwork!`

In `viewDidLoad`:

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

```

Then connect your button to this IBAction:

```
  @IBAction func showRoute(_ sender: Any) {
    let location = artwork
    let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
    location!.mapItem().openInMaps(launchOptions: launchOptions)
  }

```

---

<div class="post-metadata">

**Author:** ![drago](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/drago/32/53586_2.png) [@drago](https://forums.kodeco.com/u/drago)\
**Post date:** [January 6, 2017, 11:31pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/129 "2017-01-06T23:31:03Z")

</div>

If I create button like that:  
let smallSquare = CGSize(width: 30, height: 30)  
let button = UIButton(frame: CGRect(origin: CGPoint.zero, size: smallSquare))  
button.setBackgroundImage(UIImage(named: “car”), for: UIControlState())  
button.addTarget(self, action: #selector(Artwork.mapItem), for: .touchUpInside)  
view?.leftCalloutAccessoryView = button  
how can i add it to your navigation method?

---

<div class="post-metadata">

**Author:** ![audrey](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/audrey/32/111607_2.png) [@audrey](https://forums.kodeco.com/u/audrey)\
**Post date:** [January 7, 2017, 12:11am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/130 "2017-01-07T00:11:42Z")

</div>

if you just want to use the left callout accessory view instead of the right one, you don’t need to `addTarget`; the `calloutAccessoryControlTapped` method will run when you tap the left button.

do you also have a button on the right side?

---

<div class="post-metadata">

**Author:** ![drago](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/drago/32/53586_2.png) [@drago](https://forums.kodeco.com/u/drago)\
**Post date:** [January 7, 2017, 12:38pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/131 "2017-01-07T12:38:24Z")

</div>

I can make it, but how i can add it to your navigation method?

---

<div class="post-metadata">

**Author:** ![audrey](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/audrey/32/111607_2.png) [@audrey](https://forums.kodeco.com/u/audrey)\
**Post date:** [January 7, 2017, 9:08pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/132 "2017-01-07T21:08:12Z")

</div>

in `extension ViewController: MKMapViewDelegate`’s `viewFor annotation`, replace these two lines:

```
view.calloutOffset = CGPoint(x: -5, y: 5)
view.leftCalloutAccessoryView = UIButton(type: .detailDisclosure) as UIView

```

with your code.

---

<div class="post-metadata">

**Author:** ![drago](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/drago/32/53586_2.png) [@drago](https://forums.kodeco.com/u/drago)\
**Post date:** [January 8, 2017, 1:35am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/133 "2017-01-08T01:35:07Z")

</div>

I replaced, it don’t work((

---

<div class="post-metadata">

**Author:** ![drago](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/drago/32/53586_2.png) [@drago](https://forums.kodeco.com/u/drago)\
**Post date:** [January 8, 2017, 1:35am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/134 "2017-01-08T01:35:46Z")

</div>

I want make button, which add route to the Apple Maps.

---

<div class="post-metadata">

**Author:** ![audrey](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/audrey/32/111607_2.png) [@audrey](https://forums.kodeco.com/u/audrey)\
**Post date:** [January 8, 2017, 2:09am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/135 "2017-01-08T02:09:16Z")

</div>

leave out the `addTarget` line, and `view` isn’t optional in `viewFor annotation`, so don’t put the ?:

```
// 3
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
view.canShowCallout = true
let smallSquare = CGSize(width: 30, height: 30)
let button = UIButton(frame: CGRect(origin: CGPoint.zero, size: smallSquare))
button.setBackgroundImage(UIImage(named: "car"), for: UIControlState())
view.leftCalloutAccessoryView = button

```

---

<div class="post-metadata">

**Author:** ![drago](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/drago/32/53586_2.png) [@drago](https://forums.kodeco.com/u/drago)\
**Post date:** [January 8, 2017, 2:10pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/136 "2017-01-08T14:10:02Z")

</div>

It works. Thank you very much.

---

<div class="post-metadata">

**Author:** ![drago](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/drago/32/53586_2.png) [@drago](https://forums.kodeco.com/u/drago)\
**Post date:** [January 29, 2017, 2:22pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/137 "2017-01-29T14:22:01Z")

</div>

Hello! Can you help please? How i can add button on the map, which returns camera view to user location?

---

<div class="post-metadata">

**Author:** ![deraa](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/deraa/32/55974_2.png) [@deraa](https://forums.kodeco.com/u/deraa)\
**Post date:** [January 30, 2017, 4:43pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/138 "2017-01-30T16:43:21Z")

</div>

Hi! Great tutorial! I have an API that returns several locations and I am able to place and show them on the map without any issues. I would like to display the index number (+1) from my locations array of every location in a UIView that I created but can’t seem to figure out how to access the indexPath of my array when I select a pin. Can you please help with that? Still fairly new to programming and swift. Thanks

---

<div class="post-metadata">

**Author:** ![audrey](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/audrey/32/111607_2.png) [@audrey](https://forums.kodeco.com/u/audrey)\
**Post date:** [January 30, 2017, 9:01pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/139 "2017-01-30T21:01:53Z")

</div>

what kind of camera view?

a satellite/hybrid map type?  
`let launchOptions = [MKLaunchOptionsMapTypeKey: MKMapType.hybrid]` in the `calloutAccessoryControlTapped` method:

 ![](https://raywenderlich-com-v3-forums.s3.amazonaws.com/original/3X/b/4/b4443657f9c2d6ae764d3b9ba5fd228715680b66.png)

or something like Google Maps street view? we have a few Google Maps tutorials, for example [https://www.raywenderlich.com/81103/introduction-google-maps-ios-sdk-swift](https://www.raywenderlich.com/81103/introduction-google-maps-ios-sdk-swift)

or there’s `MKLaunchOptionsCameraKey`, which needs an `MKMapCamera` object as its value: [Apple Developer Documentation](https://developer.apple.com/reference/mapkit/mklaunchoptionscamerakey)

---

<div class="post-metadata">

**Author:** ![audrey](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/audrey/32/111607_2.png) [@audrey](https://forums.kodeco.com/u/audrey)\
**Post date:** [January 30, 2017, 9:13pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/140 "2017-01-30T21:13:12Z")

</div>

I think you need to store the index in each annotation. For Artwork, I added an `index` property, and added an index parameter to its `init` and `fromJSON` methods:

```
let index: Int
init(index: Int, title: String, locationName: String, discipline: String, coordinate: CLLocationCoordinate2D) {
  self.index = index
// ...

class func fromJSON(_ json: [JSONValue], index: Int) -> Artwork? {
// ...
return Artwork(index: index, title: title, locationName: locationName!, discipline: discipline!, coordinate: coordinate)

```

And insert `index` into the `subtitle`:

```
var subtitle: String? {
  return "\(index): \(locationName)"
}

```

In ViewController.swift, when I convert JSON into Artworks, at steps 3-5, I keep a counter, and pass its value to `fromJSON`:

```
// 3
if let jsonObject = jsonObject as? [String: Any],
// 4
let jsonData = JSONValue.fromObject(jsonObject)?["data"]?.array {
  var counter = 1
  for artworkJSON in jsonData {
    if let artworkJSON = artworkJSON.array,
    // 5
      let artwork = Artwork.fromJSON(artworkJSON, index: counter) {
      artworks.append(artwork)
    }
    counter += 1
  }
}
}

```

When I tap a pin, it shows the index:

 ![](https://raywenderlich-com-v3-forums.s3.amazonaws.com/original/3X/5/2/52b084e706a4b89f24dc80202887be97be2cf006.png)

---

<div class="post-metadata">

**Author:** ![drago](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/drago/32/53586_2.png) [@drago](https://forums.kodeco.com/u/drago)\
**Post date:** [January 31, 2017, 2:15pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/141 "2017-01-31T14:15:21Z")

</div>

I mean button like that, which return me to the user location. In your example with MapKit.

 ![](https://raywenderlich-com-v3-forums.s3.amazonaws.com/original/3X/d/5/d54615a35ebe1865290bf91635f8e0ae02e4225c.png)

---

<div class="post-metadata">

**Author:** ![audrey](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/audrey/32/111607_2.png) [@audrey](https://forums.kodeco.com/u/audrey)\
**Post date:** [February 3, 2017, 1:56am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/142 "2017-02-03T01:56:26Z")

</div>

that’s a Google Maps screen shot?

here’s what I have working in HonoluluArt:

- Embed view controller in navigation controller to get a navigation bar; add bar button with title “Here” to navigation bar
- Control-drag from bar button into `ViewController`, and create action `centerOnUserLocation(_:)`
- above this action:  
`var locationManager = CLLocationManager()`
- in the action:

```auto
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
  mapView.showsUserLocation = true
  locationManager.requestLocation()
} else {
  locationManager.requestWhenInUseAuthorization()
}

```

- At the bottom of ViewController.swift, outside the `ViewController` class:

```auto
extension ViewController: CLLocationManagerDelegate {

  func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    if let location = locations.first {
      locationManager.stopUpdatingLocation()
      centerMapOnLocation(location)
    }
  }

  func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    print(error.localizedDescription)
  }

}

```

- in `viewDidLoad()`, below `mapView.delegate = self`

```auto
locationManager.delegate = self

```

- Follow instructions at the end of the tutorial, in the section about **Info.plist item**
- Edit scheme: **Options\Core Location** : check **Allow Location Simulation** and select a **Default Location**.
- Build and run; drag the map away from simulated user location, then tap the bar button. The first time, an alert will ask permission to use your location. After allowing, you’ll have to tap the button a second time, to make the map move. But the next time you move away from the user location, then tap the button, the map will move back to the user’s location, with the glowing blue dot. Apple says to ask permission as close as possible to when you need to use their location, but you could use the `checkLocationAuthorizationStatus()` method, as described in the tutorial, to get the permission out of the way as soon as the app loads.

---

<div class="post-metadata">

**Author:** ![drago](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/drago/32/53586_2.png) [@drago](https://forums.kodeco.com/u/drago)\
**Post date:** [February 5, 2017, 1:47pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/143 "2017-02-05T13:47:18Z")

</div>

Thank you very much!

[Previous page](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355.md?page=6)

[Next page](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355.md?page=8)
