# 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:** 8

<div class="post-metadata">

**Author:** ![shah12007](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/shah12007/32/58952_2.png) [@shah12007](https://forums.kodeco.com/u/shah12007)\
**Post date:** [February 15, 2017, 12:19pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/144 "2017-02-15T12:19:33Z")

</div>

Hello! Can you help please? How can i add hyperlink in subtitle?

---

<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 15, 2017, 1:17pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/145 "2017-02-15T13:17:15Z")

</div>

[http://candycode.io/support-links-in-text-on-ios/](http://candycode.io/support-links-in-text-on-ios/)

---

<div class="post-metadata">

**Author:** ![shah12007](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/shah12007/32/58952_2.png) [@shah12007](https://forums.kodeco.com/u/shah12007)\
**Post date:** [February 15, 2017, 1:19pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/146 "2017-02-15T13:19:12Z")

</div>

Can you show example in annotation please?

---

<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 16, 2017, 7:15am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/147 "2017-02-16T07:15:09Z")

</div>

try it on your own; if you need help, contact Jure Zove (the author of the linked candycode article) — he’s super helpful and really knows his stuff!

---

<div class="post-metadata">

**Author:** ![shah12007](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/shah12007/32/58952_2.png) [@shah12007](https://forums.kodeco.com/u/shah12007)\
**Post date:** [February 18, 2017, 11:24pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/148 "2017-02-18T23:24:15Z")

</div>

Thank you!  
Can i make second subtitle under the first subtitle in annotation?

---

<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 19, 2017, 1:52am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/149 "2017-02-19T01:52:49Z")

</div>

Insert a new-line character into `subtitle`, for example:

```
var subtitle: String? {
  return locationName + "\n2nd subtitle"
}

```

And, in `viewFor annotation` customise the `detailCalloutAccessoryView`, like in my December post above:

```
let detailLabel = UILabel()
detailLabel.numberOfLines = 0
detailLabel.text = annotation.subtitle
view.detailCalloutAccessoryView = detailLabel

```

---

<div class="post-metadata">

**Author:** ![shah12007](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/shah12007/32/58952_2.png) [@shah12007](https://forums.kodeco.com/u/shah12007)\
**Post date:** [February 19, 2017, 11:21am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/150 "2017-02-19T11:21:10Z")

</div>

I tried like in your December post, but all annotations after that messed up. I make program with classes like in your part “Showing an Artwork on the Map”, without JSON.

---

<div class="post-metadata">

**Author:** ![shah12007](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/shah12007/32/58952_2.png) [@shah12007](https://forums.kodeco.com/u/shah12007)\
**Post date:** [February 21, 2017, 3:03pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/151 "2017-02-21T15:03:42Z")

</div>

I want to make big annotation. I have tried to add label in annotation. But after that all mixed up. For example: first place on the mape(titile: market1, subtitle: candyshop, coordinate: 1,1), second place on the map((titile: market2, subtitle: carwash, coordinate: 2,2)), thied place on the map(titile: market3, subtitle: restaurant, coordinate: 3,3)  
After i add  
let detailLabel = UILabel ()  
detailLabel.numberOfLines = 0  
detailLabel.text = annotation.subtitle  
view.detailCalloutAccessoryView = detailLabel  
first place on the mape(titile: market1, subtitle: restaurant, coordinate: 1,1), second place on the map((titile: market2, subtitle: candyshop, coordinate: 2,2)), thied place on the map(titile: market3, subtitle: carwash coordinate: 3,3).  
Subtitles mixed.  
Sorry for my bad English))

---

<div class="post-metadata">

**Author:** ![shah12007](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/shah12007/32/58952_2.png) [@shah12007](https://forums.kodeco.com/u/shah12007)\
**Post date:** [February 21, 2017, 3:05pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/152 "2017-02-21T15:05:31Z")

</div>

This is my annotation:

```
func mapView(_ mapView: MKMapView,
             viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    if let annotation = annotation as? Wash {
        let identifier = "Pin"
        var view: MKAnnotationView
        if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) { // 2
            dequeuedView.annotation = annotation
            view = dequeuedView
        } else {
            // 3
            view = MKAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            view.canShowCallout = true
            view.calloutOffset = CGPoint(x: -5, y: 5)
            let smallSquare = CGSize(width: 35, height: 35)
            let button = UIButton(frame: CGRect(origin: CGPoint.zero, size: smallSquare))
            button.setBackgroundImage(UIImage(named: "Navigation"), for: UIControlState())
            view.leftCalloutAccessoryView = button
            let detailLabel = UILabel()
            detailLabel.numberOfLines = 0
            detailLabel.text = annotation.subtitle
            view.detailCalloutAccessoryView = detailLabel
            

                     }
        view.image = annotation.pinImage()
        return view
    }
    return nil
}

```

this is my class:

> class Wash: 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
> }
> 
> func pinImage() -> UIImage {
> switch discipline {
> default:
> return UIImage(named: "Wash")!
> }
> }
> 
> ```
> 
> // annotation callout opens this mapItem in Maps app  
> func mapItem() → MKMapItem {  
> let addressDict = [CNPostalAddressStreetKey: subtitle!]  
> let placemark = MKPlacemark(coordinate: coordinate, addressDictionary: addressDict)
> 
> ```
> let mapItem = MKMapItem(placemark: placemark)
> mapItem.name = title
>     
> return mapItem
> }
> 
> ```
> 
> }

this is my array:

> let washs: [Wash] = [

> ```
> //Москва
> Wash(title: "Мойка", locationName: "ул. Ленинский проспект 1",
> discipline: "", coordinate: CLLocationCoordinate2D(latitude: 55.670584, longitude: 37.737914)),
> Wash(title: "Мойка",
> locationName: "Игральная 10",
> discipline: "",
> coordinate: CLLocationCoordinate2D(latitude: 54.900991, longitude: 38.080399))
> 
> ```

]

---

<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 21, 2017, 10:34pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/153 "2017-02-21T22:34:02Z")

</div>

oops! the `detailLabel.text` customisation must also happen when you reuse a dequeued view, otherwise, it keeps the text from when it was created.

To fix this, move the `detailLabel` declaration to just below `var view`, and copy the `detailLabel` lines into the `dequeuedView` setup, changing `view.detailCalloutAccessoryView` to `dequeuedView.detailCalloutAccessoryView`:

```
if let annotation = annotation as? Artwork {
  let identifier = "artPin"
  var view: MKPinAnnotationView
  let detailLabel = UILabel()
  if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
    as? MKPinAnnotationView { // 2
    dequeuedView.annotation = annotation
    detailLabel.numberOfLines = 0
    detailLabel.text = annotation.subtitle
    dequeuedView.detailCalloutAccessoryView = detailLabel
    view = dequeuedView
  } else {
    // 3
    view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
    view.canShowCallout = true
    view.calloutOffset = CGPoint(x: -5, y: 5)
    view.rightCalloutAccessoryView = UIButton(type: .detailDisclosure) as UIView

    detailLabel.numberOfLines = 0
    detailLabel.text = annotation.subtitle
    view.detailCalloutAccessoryView = detailLabel
  }
  view.pinTintColor = annotation.pinTintColor()
  return view
}

```

---

<div class="post-metadata">

**Author:** ![shah12007](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/shah12007/32/58952_2.png) [@shah12007](https://forums.kodeco.com/u/shah12007)\
**Post date:** [February 22, 2017, 6:55pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/154 "2017-02-22T18:55:05Z")

</div>

ohhh, it works!!! Thank you very much!!! You are great person!!! You really helped me.

---

<div class="post-metadata">

**Author:** ![teddyx](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/teddyx/32/58966_2.png) [@teddyx](https://forums.kodeco.com/u/teddyx)\
**Post date:** [February 28, 2017, 4:59pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/155 "2017-02-28T16:59:23Z")

</div>

Hi, Audrey!  
How can i put a phone number in a map annotation so i can tap on it and call this number?  
Can you help me?  
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:** [March 1, 2017, 12:06am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/156 "2017-03-01T00:06:32Z")

</div>

perhaps a combination of Jure’s `NSAttributedString`  
[http://candycode.io/support-links-in-text-on-ios/](http://candycode.io/support-links-in-text-on-ios/)

and the answer at

> <https://stackoverflow.com/questions/38034577/button-that-makes-a-phone-call-in-swift-2>

```
let url = NSURL(string: "tel://1234567890")!
UIApplication.sharedApplication().openURL(url)

```

---

<div class="post-metadata">

**Author:** ![teddyx](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/teddyx/32/58966_2.png) [@teddyx](https://forums.kodeco.com/u/teddyx)\
**Post date:** [March 2, 2017, 12:56am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/157 "2017-03-02T00:56:19Z")

</div>

Thanks a lot!

But how can i do this in a lot of subtitles with a lot of numbers which i can tap?  
And where i must put this code?

Sorry but i really don’t understand this 😓

---

<div class="post-metadata">

**Author:** ![naveezodiac](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/naveezodiac/32/60020_2.png) [@naveezodiac](https://forums.kodeco.com/u/naveezodiac)\
**Post date:** [March 13, 2017, 8:38am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/158 "2017-03-13T08:38:43Z")

</div>

Hi. I’m trying to build a similar app but the locations coordinates are not separate but as one string. How to get these location coordinates in the fromJson func?

This is the JSON dataset: [https://data.honolulu.gov/api/views/m2gw-xt7z/rows.json?accessType=DOWNLOAD](https://data.honolulu.gov/api/views/m2gw-xt7z/rows.json?accessType=DOWNLOAD)

Can I get that by changing slightly in your code:

let latitude = (json[21].string! as NSString).doubleValue  
let longitude = (json[21].string! as NSString).doubleValue  
let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)

If yes, how?

---

<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:** [March 13, 2017, 12:00pm UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/159 "2017-03-13T12:00:43Z")

</div>

hi Naveen: it looks to me like your coordinates are in json[10]

```
let str = "21.311542, -157.862936"
let numbers = str.components(separatedBy: CharacterSet(charactersIn: ", "))

```

`numbers` is the array [“21.311542”, “”, “-157.862936”] so your coordinates (as Strings) are `numbers.first` and `numbers.last`

---

<div class="post-metadata">

**Author:** ![naveezodiac](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/naveezodiac/32/60020_2.png) [@naveezodiac](https://forums.kodeco.com/u/naveezodiac)\
**Post date:** [March 16, 2017, 3:51am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/160 "2017-03-16T03:51:33Z")

</div>

Thx. But when I tried to convert them to double to use them in CLLocationCoordinate2D, I couldn’t. What would be the mistake?? How to convert lat and long strings to double??

'let str = (json[10].string! as NSString)  
let numbers = str.components(separatedBy: CharacterSet(charactersIn: ", "))  
let latitude = (numbers.first)  
let longitude = (numbers.last)  
let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) ’

---

<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:** [March 16, 2017, 4:11am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/161 "2017-03-16T04:11:29Z")

</div>

extract the two substrings, then convert _each_ substring to Double

```
let numbers = str.components(separatedBy: CharacterSet(charactersIn: ", "))
let latString = numbers.first 
let longString = numbers.last 
let latitude = (latString! as NSString).doubleValue
let longitude = (longString! as NSString).doubleValue
let coordinate ...

```

---

<div class="post-metadata">

**Author:** ![naveezodiac](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/naveezodiac/32/60020_2.png) [@naveezodiac](https://forums.kodeco.com/u/naveezodiac)\
**Post date:** [March 16, 2017, 4:40am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/162 "2017-03-16T04:40:16Z")

</div>

I have tried both NSString and Number formatter but What I get is the execution error right at this line: let str = (json[10].string! as NSString)

My lat and long values always return 0 or nil. Its like it won’t even take the values.

What does this error mean: EXC\_BAD\_INSTRUCTION(code=EXC\_1386\_INVOP, subcode=0x0)

---

<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:** [March 16, 2017, 5:10am UTC](https://forums.kodeco.com/t/mapkit-tutorial-getting-started/6355/163 "2017-03-16T05:10:20Z")

</div>

the first item in `data` — Aloha Tower Drive — and possibly other items, doesn’t have any coordinates; you’ll have to check there’s actually a string there, or it might be easier to manually change the null to “” (empty string) then test for that. Or manually delete those items that don’t have coordinates.

edited to add: JSON.swift returns nil if it can’t create a String from `json[10].string` so do something like this:

```
if let str = json[10].string {
  let numbers = ...
  ...
}

```

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

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