How to prevent Safari from launching when using MapLinks? - ios

I am using the following code to launch Maps from within my project:
#IBAction func navigate(){
let mapLinksSchemeURL = URL(string: "http://maps.apple.com/?daddr=\(latitude),\(longitude)&t=s&dirflg=d")
UIApplication.shared.open(mapLinksSchemeURL!, options: [:], completionHandler: nil)
}
This code launches Safari first then it continues to launch Maps. This doesn't particularly look very refined. Is there a way to skip Safari and go straight to Maps?

You have an URL that´s why it goes to Safari before it recognises the type and goes to Apple Maps.
Use the following code instead to go straight to Apple Maps:
let regionDistance:CLLocationDistance = 10000
let coordinates = CLLocationCoordinate2DMake(latitude, longitude)
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 = "Start"
mapItem.openInMaps(launchOptions: options)

Related

What is wrong with this code? When it opens up in the native maps app it takes me to a random location

Followed a video tutorial. When i build this app and hit the directions button it takes me to a random area instead of the coordinates provided. I am a beginner. Also, is there a way to pass in the locations address instead of coordinates, or should i just use the coordinates. Thanks for any responses. I am using Swift 5 in xCode 10. I changed the coordinate for privacy.
#IBAction func directionsClinic(_ sender: UIButton) {
let latitude:CLLocationDegrees = 38.465492
let longitude:CLLocationDegrees = 91.338905
let regionDistance:CLLocationDistance = 1000;
let coordinates = CLLocationCoordinate2DMake(latitude,
longitude)
let regionSpan = MKCoordinateRegion(center: coordinates,
latitudinalMeters: regionDistance, longitudinalMeters:
regionDistance)
let options = [MKLaunchOptionsMapCenterKey:
NSValue(mkCoordinate:regionSpan.center),
MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan:
regionSpan.span)]
let placemark = MKPlacemark(coordinate: coordinates)
let mapItem = MKMapItem(placemark:placemark)
mapItem.openInMaps(launchOptions: options)
}
i have just tried a few different youtube videos guides, but most were a year+ old and im not sure if the code has changed
Expected the location of the coordinates to show up in the native iphone maps app, instead it was taking me to a place on the other side of the globe.
You can try this to open with a specific address:
let baseUrl: String = "http://maps.apple.com/?q="
let encodedName = theAddress.addingPercentEncoding( withAllowedCharacters: .urlQueryAllowed) ?? ""
let finalUrl = baseUrl + encodedName
if let url = NSURL(string: finalUrl) {
UIApplication.shared.open(url)
}
The Maps app will intercept the request and open the app.

How to launch Maps app and start navigation

In my iOS app I have latitude and longitude (CLLocationCoordinate2D) of a place the user would like to reach. I want than, when the relative button is pressed, that Maps application is launched and that street navigation to that place is started too. How can I achieve that? My code up to now is:
#IBAction func launchMapsApp(sender:UIButton) {
if (sender == self.navButton) {
let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: self.currentCoordinates, addressDictionary: nil))
mapItem.name = ""
//You could also choose: MKLaunchOptionsDirectionsModeWalking
let launchOptions = [MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving, MKLaunchOptionsShowsTrafficKey: true]
mapItem.openInMapsWithLaunchOptions(launchOptions as? [String : AnyObject])
}
}
But with this the Maps app is simply launched and I simply see a map of my state (Italy) and nothing more happens. Maybe, because I have run in only in simulator?
Thanks to all
You were on the right track: This is my swift 2.0 code:
let latitude:CLLocationDegrees = xx.xxxxx
let longitude: CLLocationDegrees = xx.xxxxx
let regiondistance:CLLocationDistance = 10000
let coordinates = CLLocationCoordinate2DMake(latitude, longitude)
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 = "Name you want"
mapitem.openInMapsWithLaunchOptions(options)
I hope my code gives you some insight.
Your original code looks about right. It's possible, as you said, that the issue was how you were using the simulator. You can set a simulated location via the Debug menu in the simulator (Location -> Custom).
To launch Maps and start navigation to a specific location (as opposed to just opening Maps with a marker at the desired location, as in the other answer), I use this (in Swift 3):
let coordinates = CLLocationCoordinate2DMake(destLatitude, destLongitude)
let placemark = MKPlacemark(coordinate: coordinates, addressDictionary: nil)
let mapitem = MKMapItem(placemark: placemark)
let options = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
mapitem.openInMaps(launchOptions: options)
Hope this helps...

Calculate distance and ETA from maps in swift

I am currently using this code below that will open maps with driving guide to a certain destination.
let lat1 : NSString = "57.619302"
let lng1 : NSString = "11.954928"
let latitute:CLLocationDegrees = lat1.doubleValue
let longitute:CLLocationDegrees = lng1.doubleValue
let regionDistance:CLLocationDistance = 10000
let coordinates = CLLocationCoordinate2DMake(latitute, longitute)
let regionSpan = MKCoordinateRegionMakeWithDistance(coordinates, regionDistance, regionDistance)
let options = [
MKLaunchOptionsMapCenterKey: NSValue(MKCoordinate: regionSpan.center),
MKLaunchOptionsMapSpanKey: NSValue(MKCoordinateSpan: regionSpan.span),
MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving
]
let placemark = MKPlacemark(coordinate: coordinates, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = "Timo's Crib"
dispatch_async(dispatch_get_main_queue()) {
mapItem.openInMapsWithLaunchOptions(options)
}
}))
Now when the maps are opened you can see information such as ETA and total distance to destination. How can i extract or calculate that exact information? I only saw examples in objective c but never in swift.
You can do it using MKDirectionsRequest. First we need our current location, since from your code we see that you have the destination. I'm using CLLocationManagerDelegate method locationManager(_:didUpdateLocations:).
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let sourcePlacemark = MKPlacemark(coordinate: locations.last!.coordinate, addressDictionary: nil)
let sourceMapItem = MKMapItem(placemark: sourcePlacemark)
..
}
Perfect. Now we have source item and destination item. Now just the request (to simplify things, I put your code inside the method, but the logic behind destination place should be probably extracted from this method):
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// Get current position
let sourcePlacemark = MKPlacemark(coordinate: locations.last!.coordinate, addressDictionary: nil)
let sourceMapItem = MKMapItem(placemark: sourcePlacemark)
// Get destination position
let lat1: NSString = "57.619302"
let lng1: NSString = "11.954928"
let destinationCoordinates = CLLocationCoordinate2DMake(lat1.doubleValue, lng1.doubleValue)
let destinationPlacemark = MKPlacemark(coordinate: destinationCoordinates, addressDictionary: nil)
let destinationMapItem = MKMapItem(placemark: destinationPlacemark)
// Create request
let request = MKDirectionsRequest()
request.source = sourceMapItem
request.destination = destinationMapItem
request.transportType = MKDirectionsTransportType.Automobile
request.requestsAlternateRoutes = false
let directions = MKDirections(request: request)
directions.calculateDirectionsWithCompletionHandler { response, error in
if let route = response?.routes.first {
print("Distance: \(route.distance), ETA: \(route.expectedTravelTime)")
} else {
print("Error!")
}
}
}

Calculating expected travel time from set of polylines in iOS

I have a set of polylines defining a route. Is there some way that I can use mapkit to calculate the expected travel time along this route? If not in MapKit, then in Google Maps or any other maps api?
let sourcePlaceMark = MKPlacemark(coordinate: fromCoordinate, addressDictionary: nil)
let destPlaceMark = MKPlacemark(coordinate: toCoordinate, addressDictionary: nil)
let from = MKMapItem(placemark: sourcePlaceMark)
let to = MKMapItem(placemark: destPlaceMark)
print("caculateDirections ")
let request = MKDirectionsRequest()
request.source = from
request.destination = to
request.transportType = .Automobile
let directions = MKDirections(request: request)
directions.calculateDirectionsWithCompletionHandler { (response, error) -> Void in
if let response = response {
// Here you can get the routes and draw it on the map
let routeSeconds = response.routes.first!.expectedTravelTime
let routeDistance = response.routes.first!.distance
}
}

iOS - MapKit and navigation from a location to another

my question is about the mapkit in the iOS SDK. Is it possible to draw routes from a location to another? Is there any built-in API? If no, how can I do?
Thanks
In iOS 7, there is an API for getting the direction from a location to another called MKDirection. You can call -[MKDirection calculateDirectionsWithCompletionHandler:] method for that. This method's argument is MKDirectionsHandler block which contains the MKDirectionsResponse. The MKDirectionsResponse contains the routes data which is array of MKRoute. In each MKRoute there is a polyline (MKPolyline) which you can add these polyline as overlays to the MKMapView.
MKDirections allows you to find routes between two locations and MapKit allows you to add this routes as an overlay.
func drawRoutes(sourceLocation:CLLocationCoordinate2D ,
destinationLocation:CLLocationCoordinate2D)
{
let sourcePlacemark = MKPlacemark(coordinate: sourceLocation, addressDictionary: nil)
let destinationPlacemark = MKPlacemark(coordinate: destinationLocation, addressDictionary: nil)
let sourceMapItem = MKMapItem(placemark: sourcePlacemark)
let destinationMapItem = MKMapItem(placemark: destinationPlacemark)
let directionRequest = MKDirectionsRequest()
directionRequest.source = sourceMapItem
directionRequest.destination = destinationMapItem
directionRequest.transportType = .automobile
let directions = MKDirections(request: directionRequest)
directions.calculate {
(response, error) -> Void in
guard let response = response else {
if let error = error {
print("Error: \(error)")
}
return
}
let route = response.routes[0]
self.mapView.add((route.polyline), level: MKOverlayLevel.aboveRoads)
let rect = route.polyline.boundingMapRect
self.mapView.setRegion(MKCoordinateRegionForMapRect(rect), animated: true)
}
}

Resources