Run Apple map gps navigation directly from app - objective-c

I'm currently working on an app with a map view that opens up Apple Maps and sends in longitude and latitude so a start and stop location. So the user can navigate with the help of the Apple Maps. My question is: Is it possible so make the Apple Maps app to automatically run the navigation function? As it is now it opens the Apple Maps app with the right coordinates and annotation on the start location and the stop location, but I have to click the navigation function in order to get Apple Maps to present a navigated route from start to stop.
Here is the code that opens up Apple Maps from my own app:
// NAVIGATION ACTION SHEET
if (buttonIndex == 0) {
double toLatDouble = [to_lat doubleValue];
double toLongDouble = [to_long doubleValue];
CLLocationCoordinate2D location = CLLocationCoordinate2DMake(toLatDouble,toLongDouble);
// Apple Maps, using the MKMapItem class
MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:location addressDictionary:nil];
MKMapItem *item = [[MKMapItem alloc] initWithPlacemark:placemark];
item.name = self.toLocation;
[item openInMapsWithLaunchOptions:nil];
}
else if (buttonIndex == 1){
double fromLatDouble = [from_lat doubleValue];
double fromLongDouble = [from_long doubleValue];
CLLocationCoordinate2D location = CLLocationCoordinate2DMake(fromLatDouble,fromLongDouble);
// Apple Maps, using the MKMapItem class
MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:location addressDictionary:nil];
MKMapItem *item = [[MKMapItem alloc] initWithPlacemark:placemark];
item.name = self.toLocation;
[item openInMapsWithLaunchOptions:nil];
}else {
// Cancel
NSLog(#"User canceled navigation actionSheet");
}

As stated in the documentation of MKMapItem when you call the openInMapsWithLaunchOptions: you can also pass some options. One of them activates navigation mode.
For example, to start directions for driving, you should write:
[item openInMapsWithLaunchOptions:#{MKLaunchOptionsDirectionsModeKey :MKLaunchOptionsDirectionsModeDriving}];

Related

Opening Location with Maps and marker pin

I want to open my latitude and longitude values with modified markers and with details. So that I need to check if google map app installed I need to open with that else I will navigate into apple map.
Here I couldn't add custom pin with following code,
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"maps.apple.com/?z=12&q=%f,%f",[latitude floatValue],[longitude floatValue]]];
if (![[UIApplication sharedApplication] canOpenURL:url]) {
NSLog(#"Google Maps app is not installed");
//left as an exercise for the reader: open the Google Maps mobile website instead!
MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:rdOfficeLocation addressDictionary:nil];
MKMapItem *item = [[MKMapItem alloc] initWithPlacemark:placemark];
item.name = [NSString stringWithFormat:#"%#",[[mDataArray1 objectAtIndex:indexPath.row] valueForKey:#"NAME"]];
item.phoneNumber = [NSString stringWithFormat:#"%#",[[mDataArray1 objectAtIndex:indexPath.row] valueForKey:#"DESTINATION"]];
[item openInMapsWithLaunchOptions:nil];
} else {
[[UIApplication sharedApplication] openURL:url];
}
So please help me to add custom pin values for both apple and google maps.
You can look at how to add a custom marker in the official documentation. However, this will only work for Google Maps and not Apple Maps (in which case you'll need a different library for it)

ios actionsheet make call to external google map app and pin marker

what i need is, send lat and lng information from my own app by using actionsheet delegation to google map app, and with provided lat lng parameters, google map can draw a pin (marker)
here is my code
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
//coordinates for the place we want to display
CLLocationCoordinate2D mosqueLocation = CLLocationCoordinate2DMake(lat,lng);
if (buttonIndex==0) {
//Apple Maps, using the MKMapItem class
MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:mosqueLocation addressDictionary:nil];
MKMapItem *item = [[MKMapItem alloc] initWithPlacemark:placemark];
item.name = navBarTitle.title;
[item openInMapsWithLaunchOptions:nil];
} else if (buttonIndex==1) {
//Google Maps
//construct a URL using the comgooglemaps schema
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"comgooglemaps://?center=%f,%f",mosqueLocation.latitude,mosqueLocation.longitude]];
if (![[UIApplication sharedApplication] canOpenURL:url]) {
NSLog(#"Google Maps app is not installed");
} else {
[[UIApplication sharedApplication] openURL:url];
}
}
}
as you can see, i have apple map with red pin drawed successfully but i dont know how to draw the same pin on google map by using the comgooglemap urlscheme.
lat and lng provided, just need to send to google map app to make the draw, any suggestions would be very helpful, code example even better, thanks
Add a search for the coordinates to show a marker at that location:
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"comgooglemaps://"]]) {
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"comgooglemaps://?center=%f,%f&q=%f,%f",mosqueLocation.latitude,mosqueLocation.longitude, mosqueLocation.latitude,mosqueLocation.longitude]];
[[UIApplication sharedApplication] openURL:url];
} else {
NSLog(#"Can't use comgooglemaps://");
}

Apple URL Scheme for launching app from database information

I'm quite frustrated with an issue I'm experiencing that Is coming with a lack of information. I'm unable to locate any information regarding my issue and I'm starting to believe It isn't possible what I want to do. Here is my issue and thank you for reading.
I would like for a button on my ViewController to open Apple Maps from Longitude and Latitude coordinates that are stored in my Sqlite database Tables. I have been able to successfully do this by adding a MapView. I want to reproduce this function and have the user be able to click "Get Directions" button and It will popup the Apple Maps app with the end address setup automatically. By using #"finishLat" and #"finishLng" I'm able to collect the database information. Is this possible when using the Apple URL Scheme?
This is a sample of what the Mapview does with the information. The only part I want from this is the #"finishLat" and #"finishLng". I will also need to use the "Run" feature as well to collect the correct address.
[super viewDidLoad];
CGRect bounds = self.view.bounds;
mapview = [[MapView alloc] initWithFrame:CGRectMake(0, 0, bounds.size.width, bounds.size.height)];
[self.view addSubview:mapview];
NSArray *result = [_runs objectForKey:#"results"];
NSDictionary *arr = [result objectAtIndex:0];
arr = [arr objectForKey:#"run"];
NSMutableArray *arrPlaces = [[NSMutableArray alloc] init];
NSArray *arrDirvers = [arr objectForKey:#"drivers"];
for (int i =0; i < [arrDirvers count]; i++) {
NSDictionary *asdfg = [arrDirvers objectAtIndex:i];
Place *startPt = [[Place alloc] init];
Place *endPt = [[Place alloc] init];
NSString *temp = [asdfg objectForKey:#"startLat"];
startPt.latitude = [temp floatValue];
temp = [asdfg objectForKey:#"startLng"];
startPt.longitude = [temp floatValue];
startPt.name = [asdfg objectForKey:#"name"];
temp = [asdfg objectForKey:#"finishLat"];
endPt.latitude = [temp floatValue];
temp = [asdfg objectForKey:#"finishLng"];
endPt.longitude = [temp floatValue];
endPt.name = [asdfg objectForKey:#"name"];
[arrPlaces addObject:startPt];
[arrPlaces addObject:endPt];
This is what I have.
- (IBAction)GetDirections:(id)sender {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: #"http://maps.apple.com/?q"]];
}
Rather than using openURL: you can create an instance of MKMapItem and use openInMapsWithLaunchOptions:. You can supply the MKLaunchOptionsDirectionsModeKey option to request directions from the users current location.
Alternatively, use openMapsWithItems:launchOptions: to navigate between 2 known locations.
To open in the Apple Maps app use:
- (IBAction)GetDirections:(id)sender
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: #"http://maps.apple.com/?ll=<lattitude>,<longitude>"]];
}
If you want to open Apple Maps to a driving directions screen, you will need to use this url:
http://maps.apple.com/?saddr=<origin>&daddr=<destination>
You can also set one of these to be "Current%20Location" to use the user's current location.

Programmatically getting directions using Apple Maps

I'm a bit confused by the documentation. After some research and experimentation, this is what I have.
if ([self canUseMKMapItem]) {
[self iosTheMap];
} else {
[self googleTheMap];
}
Using this to detect whether we can use the IOS6 mapping features:
- (BOOL) canUseMKMapItem {
Class itemClass = [MKMapItem class];
return (itemClass && [itemClass respondsToSelector:#selector(openMapsWithItems:launchOptions:)]);
}
This for IOS5, using Google Maps. It automatically takes us to a screen with a list of directions from the current address (if the user allows) to the destination.
- (void)googleTheMap
{
NSNumber *userLat = [[NSNumber alloc]initWithDouble:mapView.userLocation.coordinate.latitude];
NSNumber *userLong = [[NSNumber alloc]initWithDouble:mapView.userLocation.coordinate.longitude];
NSMutableString *queryString = [NSMutableString stringWithFormat:#"http://maps.google.com/?saddr=%#,%#&daddr=",userLat,userLong];
NSString *address = [partnerObject valueForKey:ATTRIBUTE_ADDRESS];
[queryString appendString:address];
NSString *escaped = [queryString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:escaped]];
}
Here's the tricky part--this is what I'm trying to do to use Apple Maps
- (void)iosTheMap {
NSNumber * latitude = [partnerObject valueForKey:ATTRIBUTE_LATITUDE];
NSNumber * longitude = [partnerObject valueForKey:ATTRIBUTE_LONGITUDE];
CLLocationCoordinate2D coordinate;
coordinate.latitude = latitude.doubleValue;
coordinate.longitude = longitude.doubleValue;
NSMutableDictionary *addressDictionary = [[NSMutableDictionary alloc] init];
[addressDictionary setValue:[partnerObject valueForKey:ATTRIBUTE_ADDRESS] forKey:kABPersonAddressStreetKey];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:coordinate addressDictionary:addressDictionary];
MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];
[mapItem openInMapsWithLaunchOptions:nil];
}
This "works," sort of. It takes the user to a map screen with a pin showing the address. The user can tap that and get directions. However, I have a few reservations about this approach:
I have a compiler warning where I set kABPersonAddressStreetKey: "Incompatible pointer types sending 'const CFStringRef' (aka 'const struct __CFString *const') to parameter of type 'NSString *'"
The string value I am using is the full address. I use that value for the street address, although the address values are meant to be more atomic--street, city, state. It seems to work, but I'm concerned this isn't the right way to do it.
It would be nice if Apple Maps showed the name of the business/destination, not just the address.
It would be great to have Apple Maps automatically show the directions, instead of a map with the destination point, saving the user a few taps.
Any suggestions for how I can improve my approach? Although it seems to work, I suspect that it is not the right way.
You are pretty close. You need to specify the Launch Options dictionary for the openInMapsWithLaunchOptions function using the MKLaunchOptionsDirectionsModeDriving, MKLaunchOptionsDirectionsModeKey value and key.
Class itemClass = [MKMapItem class];
if (itemClass && [itemClass respondsToSelector:#selector(openMapsWithItems:launchOptions:)]) {
// Use iOS 6 maps
CLLocationCoordinate2D coordinate = [((LocationAnnotation*)[map.annotations objectAtIndex:0]) coordinate];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:coordinate addressDictionary:nil];
MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];
[mapItem openInMapsWithLaunchOptions:[NSDictionary dictionaryWithObjectsAndKeys:MKLaunchOptionsDirectionsModeDriving, MKLaunchOptionsDirectionsModeKey, nil]];
} else {
//Fall back on google
...
}

Call Maps for directions from inside your app - iOS5 iOS6

Here is a strange problem: My app should be able to call the built in Maps in iOS (both 5.1 and 6). Turns out that it works just fine under iOS6 but not under iOS5.1. The maps in iOS6 is called and the directions from saddr to daddr is traced but when I am in iOS5 the maps app is called but just one pin is put at the daddr. For some unknown reason the initial coordinates (saddr) are not showing and no direction is traced.
Here is my code:
addr = [NSString stringWithFormat: #"maps://saddr=%f,%f&daddr=%f,%f", newLocation.coordinate.latitude, newLocation.coordinate.longitude, oldLatitude, oldLongitude];
NSURL *url = [NSURL URLWithString:addr];
[[UIApplication sharedApplication] openURL:url];
I have tried change the URL to "http://maps.google.com/something" but it calls Safari instead of built in Maps app. I have noticed that the variables are being passed properly to the URL.
Any ideas?
Thanks in advance!
I had a similar problem and I had to create some conditional OS code to deal with the fact that the Google Maps application has been removed. From the new MKMapItem Reference
//first create latitude longitude object
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude,longitude);
//create MKMapItem out of coordinates
MKPlacemark* placeMark = [[MKPlacemark alloc] initWithCoordinate:coordinate addressDictionary:nil];
MKMapItem* destination = [[MKMapItem alloc] initWithPlacemark:placeMark];
if([destination respondsToSelector:#selector(openInMapsWithLaunchOptions:)])
{
//using iOS6 native maps app
[destination openInMapsWithLaunchOptions:#{MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving}];
}
else
{
//using iOS 5 which has the Google Maps application
NSString* url = [NSString stringWithFormat: #"http://maps.google.com/maps?saddr=Current+Location&daddr=%f,%f", latitude, longitude];
[[UIApplication sharedApplication] openURL: [NSURL URLWithString: url]];
}
[placeMark release];
[destination release];
To get walking directions:
For iOS 6 maps - You can set MKLaunchOptionsDirectionsModeWalking instead of MKLaunchOptionsDirectionsModeDriving
For Google maps - Add &dirflg=w to the url.
I think it's better to use the openInMapsWithLaunchOptions in iOS6 because it gives you complete control over how the maps application will respond.
You can use MKPlacemark and MKMapItem to launch the Maps app with both a coordinate and a title on the map pin:
NSString *pinTitle;
CLLocationCoordinate2D coordinate;
MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:coordinate addressDictionary:#{(id)kABPersonAddressStreetKey: pinTitle}];
MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];
if ([mapItem respondsToSelector:#selector(openInMapsWithLaunchOptions:)])
{
[mapItem openInMapsWithLaunchOptions:#{MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving}];
}
else
{
// Google Maps fallback
NSString *urlString = [NSString stringWithFormat:#"http://maps.google.com/maps?daddr=%f,%f&saddr=Current+Location", locationItem.coordinate.latitude, locationItem.coordinate.longitude];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
}
Note that you'll need to link against AddressBook.framework and also add #import <AddressBook/AddressBook.h> somewhere in your code to make use of the kABPersonAddressStreetKey constant.