I have latitude and longitude.i want to set on button click open system apple default map with set selected latitude and longitude and also should be set in map default.
At Button action paste the following code
let directionsURL = "http://maps.apple.com/?saddr=35.6813023,139.7640529&daddr=35.4657901,139.6201192"
guard let url = URL(string: directionsURL) else {
return
}
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(url)
}
This code can work for you -
import UIKit
import MapKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
showMapForMyIphone()
}
func showMapForMyIphone() {
let latitude: CLLocationDegrees = "Enter your latitude"
let longitude: CLLocationDegrees = "Enter your longitude"
let coordinates = CLLocationCoordinate2DMake(latitude, longitude)
let regionSpan = MKCoordinateRegionMakeWithDistance(coordinates, regionDistance, regionDistance)
let options =
[
MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center),
MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span)
]
//This will enable a placemerk for your map
let placemark = MKPlacemark(coordinate: coordinates, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = "Place Name"
mapItem.openInMaps(launchOptions: options)
}
Related
I am trying to add multiple poly lines onto a map using mkmapkit. These poly lines indicate walking zones in my area. The problem is that my code is too bulky for a large amount of walking zones.
At the moment my code only indicates 2 walking routes but for instance if I want to add 100 or 1000 walking routes the code would be massive. I'm sure there is a way I could stream line this code so I could add in multiple walking zones with a lot less code but in not too sure the best way to go about it.
import UIKit
import MapKit
class customPin: NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D
var title: String?
var subtitle: String?
init(pinTitle:String, pinSubTitle:String, location:CLLocationCoordinate2D) {
self.title = pinTitle
self.subtitle = pinSubTitle
self.coordinate = location
}
}
class ViewController: UIViewController, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//co-ordinates
let zone1S = CLLocationCoordinate2D(latitude: 52.100525, longitude: -9.623071)
let zone1E = CLLocationCoordinate2D(latitude: 52.07241, longitude: -9.575299)
let zone2S = CLLocationCoordinate2D(latitude: 52.054161, longitude: -9.385031)
let zone2E = CLLocationCoordinate2D(latitude: 52.081185, longitude: -9.247033)
//pins
let zone1PinS = customPin(pinTitle: "Zone 1 Start", pinSubTitle: "", location: zone1S)
let zone1PinE = customPin(pinTitle: "Zone 1 End", pinSubTitle: "", location: zone1E)
self.mapView.addAnnotation(zone1PinS)
self.mapView.addAnnotation(zone1PinE)
let zone2PinS = customPin(pinTitle: "Zone 2 Start", pinSubTitle: "", location: zone2S)
let zone2PinE = customPin(pinTitle: "Zone 2 End", pinSubTitle: "", location: zone2E)
self.mapView.addAnnotation(zone2PinS)
self.mapView.addAnnotation(zone2PinE)
let zone1PlacemarkS = MKPlacemark(coordinate: zone1S)
let zone1PlacemarkE = MKPlacemark(coordinate: zone1E)
let zone2PlacemarkS = MKPlacemark(coordinate: zone2S)
let zone2PlacemarkE = MKPlacemark(coordinate: zone2E)
//add polyline to map
let directionRequestZone1 = MKDirections.Request()
directionRequestZone1.source = MKMapItem(placemark: zone1PlacemarkS)
directionRequestZone1.destination = MKMapItem(placemark: zone1PlacemarkE)
let directionRequestZone2 = MKDirections.Request()
directionRequestZone2.source = MKMapItem(placemark: zone2PlacemarkS)
directionRequestZone2.destination = MKMapItem(placemark: zone2PlacemarkE)
//type of commute
directionRequestZone1.transportType = .automobile
directionRequestZone2.transportType = .automobile
let directions1 = MKDirections(request: directionRequestZone1)
directions1.calculate { (response, error) in
guard let directionResonse = response else {
if let error = error {
print("we have error getting directions==\(error.localizedDescription)")
}
return
}
let route = directionResonse.routes[0]
self.mapView.addOverlay(route.polyline, level: .aboveRoads)
let rect = route.polyline.boundingMapRect
//zooming in on location
// self.mapView.setRegion(MKCoordinateRegion(rect), animated: true)
}
let directions2 = MKDirections(request: directionRequestZone2)
directions2.calculate { (response, error) in
guard let directionResonse = response else {
if let error = error {
print("we have error getting directions==\(error.localizedDescription)")
}
return
}
let route2 = directionResonse.routes[0]
self.mapView.addOverlay(route2.polyline, level: .aboveRoads)
let rect = route2.polyline.boundingMapRect
//zooming in on location
// self.mapView.setRegion(MKCoordinateRegion(rect), animated: true)
}
//set delegate for mapview
self.mapView.delegate = self
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.red
renderer.lineWidth = 5.0
return renderer
}
}
This is how it looks:
UPDATE:
My attempt to use loops hasn't worked. I seem to have a loop working for dropping the start and end zone pins however it doesn't seem to work for drawing the poly lines.
struct Location {
let title: String
let latitude: Double
let longitude: Double
}
let locationsStart = [
Location(title: "Start", latitude: 52.100525, longitude: -9.623071)
]
let locationsEnd = [
Location(title: "End", latitude: 52.07241, longitude: -9.575299)
]
for location in locationsStart {
let annotation = MKPointAnnotation()
annotation.title = location.title
annotation.coordinate = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)
mapView.addAnnotation(annotation)
let directionRequestZone1 = MKDirections.Request()
let zonePlacemarkS = MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude))
let directionRequest = MKDirections.Request()
directionRequest.source = MKMapItem(placemark: zonePlacemarkS)
directionRequestZone1.transportType = .automobile
}
for location in locationsEnd {
let annotation = MKPointAnnotation()
annotation.title = location.title
annotation.coordinate = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)
mapView.addAnnotation(annotation)
let directionRequestZone1 = MKDirections.Request()
let zonePlacemarkE = MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude))
let directionRequest = MKDirections.Request()
directionRequest.destination = MKMapItem(placemark: zonePlacemarkE)
directionRequestZone1.transportType = .automobile
let directions1 = MKDirections(request: directionRequestZone1)
directions1.calculate { (response, error) in
guard let directionResonse = response else {
if let error = error {
print("we have error getting directions==\(error.localizedDescription)")
}
return
}
let route = directionResonse.routes[0]
self.mapView.addOverlay(route.polyline, level: .aboveRoads)
let rect = route.polyline.boundingMapRect
}
}
//set delegate for mapview
self.mapView.delegate = self
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.red
renderer.lineWidth = 5.0
return renderer
}
I adapted your code as follows:
let zone1S = CLLocationCoordinate2D(latitude: 52.100525, longitude: -9.623071)
let zone1E = CLLocationCoordinate2D(latitude: 52.07241, longitude: -9.575299)
let zone2S = CLLocationCoordinate2D(latitude: 52.054161, longitude: -9.385031)
let zone2E = CLLocationCoordinate2D(latitude: 52.081185, longitude: -9.247033)
let zones = [(start:zone1S, end:zone1E), (start:zone2S, end:zone2E)]
for (i, zone) in zones.enumerated() {
let pinS = customPin(pinTitle: "Zone \(i+1) Start", pinSubTitle: "", location: zone.start)
let pinE = customPin(pinTitle: "Zone \(i+1) End", pinSubTitle: "", location: zone.end)
self.mapView.addAnnotation(pinS)
self.mapView.addAnnotation(pinE)
let placeS = MKPlacemark(coordinate: zone.start)
let placeE = MKPlacemark(coordinate: zone.end)
let req = MKDirections.Request()
req.source = MKMapItem(placemark: placeS)
req.destination = MKMapItem(placemark: placeE)
req.transportType = .automobile
let dir = MKDirections(request: req)
dir.calculate { (response, error) in
guard let directionResponse = response else {
if let error = error {
print("we have error getting directions==\(error.localizedDescription)")
}
return
}
DispatchQueue.main.async {
let route = directionResponse.routes[0]
self.mapView.addOverlay(route.polyline, level: .aboveRoads)
}
}
}
Clearly this can be trivially extended to any number of zones. (It may be that we should be using something like a DispatchGroup to prevent the networking calculate calls from piling up too quickly, but the goal was to solve it for two pairs of coordinates and this seems to work fine.)
I am using firebase as my backend. In this application I have used mapkit and firebase. I want to track the location of user. But when I am doing the location of user is sucessfully uploaded to firebase but in my application the view is reloaded.
my code:-
#IBOutlet weak var map:MKMapView!
let locationManager = CLLocationManager()
var lat = [Double]()
var lon = [Double]()
var ref:DatabaseReference!
var uid = ""
override func viewDidLoad() {
super.viewDidLoad()
map.delegate = self
locationManager.delegate = self
ref = Database.database().reference().child("users").child(uid)
ref.child("locations").queryOrderedByKey().observe(.childAdded, with: { (snapshot) in
print("func snapshot \(snapshot)")
let dict = snapshot.value as! [String:Double]
let lat = dict["latitude"]
let lon = dict["longitude"]
print("latidue = \(lat!)")
print("longitude = \(lon!)")
self.lat.append(lat!)
self.lon.append(lon!)
})
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let location = CLLocationCoordinate2D(latitude: lat.first!,longitude: lon.first!)
let destinationLocation = CLLocationCoordinate2D(latitude: lat.last!, longitude:lon.last!)
let sourcePlacemark = MKPlacemark(coordinate: location, addressDictionary: nil)
let destinationPlacemark = MKPlacemark(coordinate: destinationLocation, addressDictionary: nil)
let sourceMapItem = MKMapItem(placemark: sourcePlacemark)
let destinationMapItem = MKMapItem(placemark: destinationPlacemark)
let sourceAnnotation = MKPointAnnotation()
if let location = sourcePlacemark.location {
sourceAnnotation.coordinate = location.coordinate
}
let destinationAnnotation = MKPointAnnotation()
if let location = destinationPlacemark.location {
destinationAnnotation.coordinate = location.coordinate
}
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.map.add((route.polyline), level: MKOverlayLevel.aboveRoads)
let rect = route.polyline.boundingMapRect
self.map.setRegion(MKCoordinateRegionForMapRect(rect), animated: true)
}
let span = MKCoordinateSpanMake(0.05, 0.05)
let region = MKCoordinateRegion(center: location, span: span)
map.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = location
map.addAnnotation(annotation)
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.red
renderer.lineWidth = 4.0
return renderer
}
I don't want to reload my whole view just want to render my mapview whenever new cordinate is uploaded.
Remove code from viewDidAppear and put it inside the observe childAdded callback
I am trying to launch the map automatically when the screen loads.
Can this be done? Launch this function on view did appear.
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
if let anno = view.annotation {
let place = MKPlacemark(coordinate: anno.coordinate)
let destination = MKMapItem(placemark: place)
destination.name = "Vehicle Sighting"
let regionDistance: CLLocationDistance = 1000
let regionSpan = MKCoordinateRegionMakeWithDistance(anno.coordinate, regionDistance, regionDistance)
let options = [MKLaunchOptionsMapCenterKey: NSValue (mkCoordinate: regionSpan.center), MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span), MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving] as [String : Any]
MKMapItem.openMaps(with: [destination], launchOptions: options)
}
}
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
an alternative version using #Reinier answer.
this shows how it was implemented into an action the view controller before with no need to go to the next controller to launch in view did load. Also how i got the coordinates from a postcode
var addressCode = [[String: Double]]()
#IBAction func onMapPressed(_ sender: Any) {
let address = postCode
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(address) {
placemarks, error in
let placemark = placemarks?.first
let lat = placemark?.location?.coordinate.latitude
let lon = placemark?.location?.coordinate.longitude
// let locationTitle = self.places]
let latLon = ["latitude":lat!, "longitude": lon!]
self.addressCode.append(latLon)
for location in self.addressCode {
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: location["latitude"]!, longitude: location["longitude"]!)
self.openMapsAppWithLocation(coordinates: annotation.coordinate, placeName: self.makeLabel.text!)
}
}
}
I am having a bit of trouble understanding Apple's MapKit in Swift 3.
I found an example here: How to open maps App programmatically with coordinates in swift?
public func openMapForPlace(lat:Double = 0, long:Double = 0, placeName:String = "") {
let latitude: CLLocationDegrees = lat
let longitude: CLLocationDegrees = long
let regionDistance:CLLocationDistance = 100
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 = placeName
mapItem.openInMaps(launchOptions: options)
}
This works absolutely swimmingly, except that I need to use an address instead of coordinates in this case.
I have found methods for doing this using google maps, but I cant seem to find a specific answer for Apple Maps, if it exists, I've completed glazed over it.
If anyone can help me to understand what the correct approach is, that would be amazing. I'm using:
Xcode 8.3.1
Swift 3.1
macOS
Targeting iOS 10+
You need to use the Geocoding service to convert an address to the corresponding geolocation.
For instance, add this function to your toolkit:
func coordinates(forAddress address: String, completion: #escaping (CLLocationCoordinate2D?) -> Void) {
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(address) {
(placemarks, error) in
guard error == nil else {
print("Geocoding error: \(error!)")
completion(nil)
return
}
completion(placemarks.first?.location?.coordinate)
}
}
and then use it like this:
coordinates(forAddress: "YOUR ADDRESS") {
(location) in
guard let location = location else {
// Handle error here.
return
}
openMapForPlace(lat: location.latitude, long: location.longitude)
}
You need to use geoCode to get the coordinates from the address... This should work:
let geocoder = CLGeocoder()
geocoder.geocodeAddressString("ADDRESS_STRING") { (placemarks, error) in
if error != nil {
//Deal with error here
} else if let placemarks = placemarks {
if let coordinate = placemarks.first?.location?.coordinate {
//Here's your coordinate
}
}
}
I have latitude and longitude that I want to open into my map application. I tried this code from HERE.
func goToMap(){
var lat1 : NSString = self.venueLat
var lng1 : NSString = self.venueLng
var latitude:CLLocationDegrees = lat1.doubleValue
var longitude:CLLocationDegrees = lng1.doubleValue
var coordinate = CLLocationCoordinate2DMake(latitude, longitude)
var placemark : MKPlacemark = MKPlacemark(coordinate: coordinate, addressDictionary:nil)
var mapItem:MKMapItem = MKMapItem(placemark: placemark)
mapItem.name = "Target location"
let launchOptions:NSDictionary = NSDictionary(object: MKLaunchOptionsDirectionsModeDriving, forKey: MKLaunchOptionsDirectionsModeKey)
var currentLocationMapItem:MKMapItem = MKMapItem.mapItemForCurrentLocation()
MKMapItem.openMapsWithItems([currentLocationMapItem, mapItem], launchOptions: launchOptions)
}
This function successfully open maps but it doesn't show any pin. Also it shows user location which I don't want. I only want a pin on the map for the provided latitude and longitude.
This code is working fine for me.
func openMapForPlace() {
let lat1 : NSString = self.venueLat
let lng1 : NSString = self.venueLng
let latitude:CLLocationDegrees = lat1.doubleValue
let longitude:CLLocationDegrees = lng1.doubleValue
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 = "\(self.venueName)"
mapItem.openInMapsWithLaunchOptions(options)
}
For swift 3.0:
import UIKit
import MapKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
openMapForPlace()
}
func openMapForPlace() {
let latitude: CLLocationDegrees = 37.2
let longitude: CLLocationDegrees = 22.9
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 = "Place Name"
mapItem.openInMaps(launchOptions: options)
}
}
Swift 5:
let latitude: CLLocationDegrees = Double(K.latitude)!
let longitude: CLLocationDegrees = Double(K.longitude)!
let regionDistance:CLLocationDistance = 10000
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, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = K.companyName
mapItem.openInMaps(launchOptions: options)
If you just want to give the user driving directions, here's the latest Swift syntax in its simplest form:
let coordinate = CLLocationCoordinate2DMake(theLatitude,theLongitude)
let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: coordinate, addressDictionary:nil))
mapItem.name = "Target location"
mapItem.openInMaps(launchOptions: [MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving])
You could call class function of MKMapItem passing items there, it uses only first and last for source / destination appropriately, if you want pass more than two items.
Swift 5, 4
let source = MKMapItem(placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: lat, longitude: lng)))
source.name = "Source"
let destination = MKMapItem(placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: lat, longitude: lng)))
destination.name = "Destination"
MKMapItem.openMaps(
with: [source, destination],
launchOptions: [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
)
or using extension:
extension MKMapItem {
convenience init(coordinate: CLLocationCoordinate2D, name: String) {
self.init(placemark: .init(coordinate: coordinate))
self.name = name
}
}
let source = MKMapItem(coordinate: .init(latitude: lat, longitude: lng), name: "Source")
let destination = MKMapItem(coordinate: .init(latitude: lat, longitude: lng), name: "Destination")
MKMapItem.openMaps(
with: [source, destination],
launchOptions: [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
)
The MKMapItem approach above works great if you want granular control over the information that is displayed in Maps.
Otherwise, the code below works great as well, :
// Open and show coordinate
let url = "http://maps.apple.com/maps?saddr=\(coord.latitude),\(coord.longitude)"
UIApplication.shared.openURL(URL(string:url)!)
// Navigate from one coordinate to another
let url = "http://maps.apple.com/maps?saddr=\(from.latitude),\(from.longitude)&daddr=\(to.latitude),\(to.longitude)"
UIApplication.shared.openURL(URL(string:url)!)
However, the code above does not let you to send in a custom name of the place. Instead, it will show the address.
The code above also lets you navigate from any source coordinate, which I don't know if you can do with the MKMapItem approach.
This works as a charm for me
let coordinate = CLLocationCoordinate2DMake(theLatitude, theLongitude)
let region = MKCoordinateRegionMake(coordinate, MKCoordinateSpanMake(0.01, 0.02))
let placemark = MKPlacemark(coordinate: coordinate, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
let options = [
MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: region.center),
MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: region.span)]
mapItem.name = theLocationName
mapItem.openInMaps(launchOptions: options)
You can use below code to show PIN on lat, long in to Apple map.
let coordinates = CLLocationCoordinate2DMake(-37.848854,144.990295)
let regionSpan = MKCoordinateRegionMakeWithDistance(coordinates, 1000, 1000)
let placemark = MKPlacemark(coordinate: coordinates, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = “Desired place”
mapItem.openInMaps(launchOptions:[
MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center)
] as [String : Any])
If what you want is something simple without importing any framework you can just create a URL: https://maps.apple.com/?ll=\(latitude),\(longitude)
Is similar to #saniel-saidi response but this one opens just the map with location sent, not the navigation thing
Update to the practical Daniel Saidi answer. This example is for telling only the destination coordinates. Maps will get as origin the user current position.
let url = URL(string: "http://maps.apple.com/maps?saddr=&daddr=\(lat),\(lon)")
UIApplication.shared.open(url!)
I know all answers are complete but here I got an answer which is easier to copy paste & also gives the user options to routing with Apple Maps, Google Map & Waze.
Working with Swift 5+
https://stackoverflow.com/a/60930491/6449292
Might help someone...
The simplest way to open the Apple Maps app and show a pin on the custom location with a custom title is that:
let url = URL(string: "maps://?q=Title&ll=\(latitude),\(longitude)")!
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
}
Look here for more options:
https://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html
Swift 5 Solution:
Open Apple Map OR Google Map Programmatically
let actionSheet = UIAlertController(title: "Open Location", message: "Choose an app to open direction", preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Google Maps", style: .default, handler: { _ in
// Pass the coordinate inside this URL
self.openGoogleMap()
}))
actionSheet.addAction(UIAlertAction(title: "Apple Maps", style: .default, handler: { _ in
// Pass the coordinate that you want here
self.openAppleMap()
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
//Function defination here
func openAppleMap(){
guard let lat = bookingData.gpsLatitude, let latDouble = Double(lat) else {return }
guard let long = bookingData.gpsLongitude, let longDouble = Double(long) else {return }
let coordinate = CLLocationCoordinate2DMake(latDouble,longDouble)
let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: coordinate, addressDictionary: nil))
mapItem.name = "Destination"
mapItem.openInMaps(launchOptions: [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving])
}
func openGoogleMap() {
guard let lat = bookingData.gpsLatitude, let latDouble = Double(lat) else {return }
guard let long = bookingData.gpsLongitude, let longDouble = Double(long) else {return }
if (UIApplication.shared.canOpenURL(URL(string:"comgooglemaps://")!)) { //if phone has an app
if let url = URL(string: "comgooglemaps-x-callback://?saddr=&daddr=\(latDouble),\(longDouble)&directionsmode=driving") {
UIApplication.shared.open(url, options: [:])
}}
else {
//Open in browser
if let urlDestination = URL.init(string: "https://www.google.co.in/maps/dir/?saddr=&daddr=\(latDouble),\(longDouble)&directionsmode=driving") {
UIApplication.shared.open(urlDestination)
}
}
}
Don't forget to write this in info.plist
<key>LSApplicationQueriesSchemes</key>
<array>
<string>comgooglemaps</string>
<string>comgooglemaps-x-callback</string>
</array>