Reputation: 213
I have a local search that creates annotations for each search result. I'm trying to add an call out accessory to each of the annotations, and once that will be pressed, the Maps app will open and set directions on how to get to the certain location.
The problem that I am having is that in order for the call out accessory to work correctly, you have to get the address using place marks in the Address Book import. I've done plenty of searching and can't figure out how to set it up correctly where I can covert the annotation coordinates into a kABPersonAddressStreetKey
so the Maps app can read it correctly. Below is my code for the search function, and the open Maps app function.
func performSearch() -> MKMapItem {
matchingItems.removeAll()
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = searchText.text
request.region = mapView.region
let search = MKLocalSearch(request: request)
search.startWithCompletionHandler({(response:
MKLocalSearchResponse!,
error: NSError!) in
if error != nil {
println("Error occured in search: \(error.localizedDescription)")
} else if response.mapItems.count == 0 {
println("No matches found")
} else {
println("Matches found")
for item in response.mapItems as! [MKMapItem] {
println("Name = \(item.name)")
println("Phone = \(item.phoneNumber)")
self.matchingItems.append(item as MKMapItem)
println("Matching items = \(self.matchingItems.count)")
var annotation = MKPointAnnotation()
var coordinates = annotation.coordinate
var location = CLLocation(latitude: annotation.coordinate.latitude, longitude: annotation.coordinate.longitude)
var street = // Insert code here for getting address from coordinates
var addressDictionary = [String(kABPersonAddressStreetKey): street]
var placemark = MKPlacemark(coordinate: coordinates, addressDictionary: addressDictionary)
var mapItem = MKMapItem(placemark: placemark)
return mapItem
annotation.coordinate = item.placemark.coordinate
annotation.title = item.name
self.mapView.addAnnotation(annotation)
}
}
})
}
func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!,
calloutAccessoryControlTapped control: UIControl!) {
let location = view.annotation as! FirstViewController
let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
location.performSearch().openInMapsWithLaunchOptions(launchOptions)
}
Any help would be greatly appreciated, thanks in advance.
Upvotes: 3
Views: 4177
Reputation: 131398
Your assumption is wrong. You can generate a request for driving directions using lat/long coordinates just as easily as using addresses.
Here's what you do:
Get the MKMapItem for the user-selected pin
Create a second MKMapItem for the user's current location using the MKMapItem method mapItemForCurrentLocation().
Call the MKMapItem class method openMapsWithItems() passing in the two MKMapItems for the current location and the destination, and a launchOptions dictionary specifying MKLaunchOptionsDirectionsModeDriving.
In your calloutAccessoryControlTapped method you get passed an annotation view. The MKAnnotationView class has an annotation property, an object that conforms to the MKAnnotation property.
An MKAnnotation object has a coordinate property.
You can fetch the annotation object from the annotation view, and the coordinate from the annotation object.
You would then take the coordinate and use it to create an MKPlacemark, using the initWithCoordinate:addressDictionary:
method (passing in a nil addressDictionary).
That call might look like this:
let sourcePlacemark = MKPlacemark(
coordinate: fromCoordinate,
addressDictionary: nil)
You'd then take the place mark and use it to create an MKMapItem, using the initWithPlacemark:
method.
There is a single MKMapView method, forCurrentLocation()
that returns a MKMapItem for the current location.
Upvotes: 1