I am fetching location data (like the coordinates used below) from Google's Places API.
When linking to Apple Maps for navigation from my app, I am currently using:
https://maps.apple.com/?daddr=[latitude],[longitude]
When Maps opens, it presents the coordinates for a short amount of time before resolving to an address. What I want is for the name of the destination to appear instead of coordinates or an address. Since I am using React Native, I would prefer a javascript-only solution (knowing that this essentially restricts a solution to this question to a url).
I have tried combinations of other parameters listed here to no avail.
Try with this function, you only need to pass the coordinates and place name, this works, I use this in several projects
static func openMapsAppWithLocation(coordinates:CLLocationCoordinate2D,placeName:String)
{
let regionDistance:CLLocationDistance = 10000
let regionSpan = MKCoordinateRegionMakeWithDistance(coordinates, regionDistance, regionDistance)
let options = [
MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center),
MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span)
]
let placemark = MKPlacemark(coordinate: coordinates, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = placeName
mapItem.openInMaps(launchOptions: options)
}
Hope this helps
Related
This is my custom location set inside the iOS 10.0 iPhone 6 and iOS 11.2 iPhone 6 simulators.
And this is the code by which I am trying to open the iPhone's inbuilt Apple Map and show the directions from user's (above set) current location to the provided destination locations.
let regionDistance: CLLocationDistance = 1000
let coordinates = CLLocationCoordinate2D(latitude: 26.025860999999999, longitude: 56.089238999999999)
let regionSpan = MKCoordinateRegionMakeWithDistance(coordinates, regionDistance, regionDistance)
let options = [MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center),
MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span),
MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving] as [String : Any]
let placemark = MKPlacemark(coordinate: coordinates, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = "Federal Electricity & Water Authority"
mapItem.openInMaps(launchOptions: options)
but this is not working for at all. It's showing me the error like below,
Note:
I have given the location access permission to the default Map
application.
All 4 MKLaunchOptionsDirectionsModeKey is not showing
the direction.
Tested it on the Simulator and a real device and it is not working in either place.
Setting destination coordinates like this doesn't help. let coordinates = CLLocationCoordinate2D(latitude: 26.025861, longitude: 56.089239)
Please help!
As Indrajeet commented, the directions in iPhone's Apple Map is limited to the countries which are listed in this URL.
So in my case, UAE is not listed currently.
Will update this answer in future once UAE will be listed.
It's quite easy to add an annotation to a MapKit view which is inside your app.
theMap: MKMapView!
let pa = MKPointAnnotation()
pa.title = "title!!" etc
theMap.addAnnotation(pa)
But how the heck do you make the Maps App add an annotation??
Here's exactly how to open the Maps App to a certain address..
func appleMapApp() {
quickAddressText = "123 Smith St 90210"
let bottomText = "This shows at BOTTOM Of Maps App screen."
let g = CLGeocoder()
g.geocodeAddressString(quickAddressText) { placemarks, error in
if let found = placemarks?.first, let lok = found.location {
let p = MKPlacemark(coordinate: lok.coordinate, addressDictionary: nil)
let mapItem = MKMapItem(placemark: p)
mapItem.name = bottomText
mapItem.openInMaps(launchOptions: showing(location: lok))
}
}
}
// convenient function...
func showing(location: CLLocation, meters m: CLLocationDistance = 1000)->[String : Any]? {
let cr = MKCoordinateRegionMakeWithDistance(location.coordinate, m,m)
let options = [
MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: cr.center),
MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: cr.span)
]
return options
}
That's great - but how the heck do you pass in a MKPointAnnotation to the actual Maps app??
(Again - it's easy to add a MKPointAnnotation on a map view inside your own app.)
Any ideas? Is it actually possible??
I think openInMaps limits you only to the five possible launch options. But I wonder if you could get Apple Maps to open in the original way, openURL and maps.apple.com/maps, as shown in this SO question. With the newest iOS versions, though, it seems you also need to register the URL you're using in your info.plist under "URL Types ... URL Schemes" or "LSApplicationQueriesSchemes". You might be able to pass an annotation as a parameter with the URL.
I'm trying to implement a function that open the Apple Map app's driving direction screen by passing actual address.
The address is not just random addresses but business addresses which are mostly registered and searchable on Apple maps. So by passing the address, it should be matched and correctly show direction to that business instead of pointing to an unknown annotation on the map. Such case happens when I pass longitude and latitude directly so I don't want to use geocodeAddressString() to convert the address to geocoordination.
How can I achieve it?
Simply use the Apple Maps API. If you can find a business by tiping its name in Apple Maps, you can find it through the APIs. In your case, the correct parameter is daddr, like this:
http://maps.apple.com/?daddr=1+Infinite+Loop,+Cupertino,+CA
You can combine multiple parameters, such as your starting location:
http://maps.apple.com/?saddr=1024+Market+St,+San+Francisco,+CA&daddr=1+Infinite+Loop,+Cupertino,+CA
You can find the list of supported parameters here.
Remember to open the URL via UIApplication.shared().open(url: URL, options: [String: AnyObject], completionHandler: ((Bool) -> Void)?) - in iOS 10 - or UIApplication.shared.open(url: URL)
You could call maps with a url (as detailed by Nicola) but there is also a proper api for this : MKMapItem
basically you create map items for POIs / addresses [1 or more]
open Maps with them [use the launchOptions for starting with directions]
func showMap() {
//---
//create item 1
//address
let coords = CLLocationCoordinate(coordinateField.doubleValue!,coordinateField.doubleValue!)
let addressDict =
[CNPostalAddressStreetKey: address.text!,
CNPostalAddressCityKey: city.text!,
CNPostalAddressStateKey: state.text!,
CNPostalAddressPostalCodeKey: zip.text!]
//item
let place = MKPlacemark(coordinate: coords!,
addressDictionary: addressDict)
let mapItem = MKMapItem(placemark: place)
//---
//create item 2
//address
let coords2 = CLLocationCoordinate(coordinateField2.doubleValue!,coordinateField2.doubleValue!)
let addressDict2 =
[CNPostalAddressStreetKey: address2.text!,
CNPostalAddressCityKey: city2.text!,
CNPostalAddressStateKey: state2.text!,
CNPostalAddressPostalCodeKey: zip2.text!]
//item2
let place2 = MKPlacemark(coordinate: coords2!,
addressDictionary: addressDict2)
let mapItem2 = MKMapItem(placemark: place2)
//-----
//launch it
let options = [MKLaunchOptionsDirectionsModeKey:
MKLaunchOptionsDirectionsModeDriving]
//for 1 only.
mapItem.openInMaps(launchOptions: options)
//for 1 or N items
var mapItems = [mapItem, mapItem2] //src to destination
MKMapItem.openMaps(withItems:mapItems, launchOptions: options)
}
I am trying to convert the location address to coordinates and open it inside the maps app, but I am getting this error when the function is called.
[Client] Geocode error: <private>. That is the only thing printed inside the console.
#IBAction func openinmaps(_ sender: AnyObject) {
var geocoder: CLGeocoder = CLGeocoder()
var location = "1 Infinite Loop"
geocoder.geocodeAddressString(location,completionHandler: {(placemarks: [CLPlacemark]?, error: NSError?) -> Void in
if (placemarks?.count > 0) {
var topResult: CLPlacemark = (placemarks?[0])!
var placemark: MKPlacemark = MKPlacemark(placemark: topResult)
let regionDistance:CLLocationDistance = 10000
let coordinates = CLLocationCoordinate2DMake(placemark.coordinate.latitude, placemark.coordinate.latitude)
let regionSpan = MKCoordinateRegionMakeWithDistance(coordinates, regionDistance, regionDistance)
let options = [
MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center),
MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span)
]
let mapItem = MKMapItem(placemark: placemark)
mapItem.openInMaps(launchOptions: options)
}
})
}
My extension for CLLocationManagerDelegate was randomly crashing because of the same error: [Client] Geocode error: <private> in swift 3.0.
The thing is:
geocoder.reverseGeocodeLocation(startLocation, completionHandler: {
placemarks, error in
})
placemarks sometimes was returning nil...
So... I realised that I was playing with my HTTP proxy in order to test some request to the Google API from my device with the Charles Proxy. Removing the Manual HTTP proxy address on my iPhone did the trick and geocoder was working fine again.
I hope it helps.
PD: Nevermind...after 30 seconds or even less, app crashes with the same debug message: [Client] Geocode error:
I had the same issue, it seems there is a limit when geocoding by address and this is the error for this.
My workaround was to put sleep(1) after each geocode in my loop, find the location latitude and longitude and post them back into my database against each venue I was plotting.
This means it now doesn't need to use the geocoder to plot the annotations on the map as it just uses the lat and long to do so. This will work for fixed sets of data but for stuff on the fly you would need another way. Apparently sleep(2) will enable you to plot continuously through large volumes of data but ends up taking a while for everything to plot.
I've added a default lat and long of 0.0 into my database and upon launching the app it will scan through to find any new venues and will then geocode these and post the lat and long back. I had to do a couple of runs through originally to get ~700 venues lats and longs but I've had no trouble since.
When ill load any placemark from my app into the Apple Maps App - it takes up to 15 Seconds to show a route.
First you see for maybe 1 second your position, then you see North America, and then (after 10-15 Seconds) you get your route.
Is there any chance to optimize the performance here? This is how i start the route at the moment (Ill provide already a lon and lat value)
let placemark = MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: CLLocationDegrees(lat),longitude: CLLocationDegrees(lon)), addressDictionary: nil)
let aMapItem = MKMapItem(placemark: placemark
aMapItem.name = mapItem.name
let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeWalking]
let currentLocationMapItem:MKMapItem = MKMapItem.mapItemForCurrentLocation()
MKMapItem.openMapsWithItems([currentLocationMapItem, aMapItem], launchOptions: launchOptions)
Thanks in advance.