How Can I get Direction on an iPhone iOS 6 App in

2020-01-31 04:03发布

问题:

I want to update an app from iOS < 6 that uses Google Maps. My app has a lot of pins on a map, and, when a user taps over one of them, the iPhone call Maps like a shared application to get direction from his current location and the destination with the native Maps App. With iOS 6, the same instructions (posted below) obviously open Safari instead Google Maps. I want to write an if-cycle that checks the iOS installed on the device: if < 6, nothing changed, if iOS > 6 then..... (open new apple maps and get direction there).

Someone can help me please?

Here the Action before iOS 6

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {

    [self.navigationController pushViewController:[[UIViewController alloc] init] animated:YES];


    NSString* addr = [NSString stringWithFormat:@"http://maps.google.com/maps?daddr=%1.6f,%1.6f&saddr=Posizione attuale", view.annotation.coordinate.latitude,view.annotation.coordinate.longitude];

    NSURL* url = [[NSURL alloc] initWithString:[addr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];  
    [[UIApplication sharedApplication] openURL:url];



}

回答1:

I recommend using [MKMapItem openMapsWithItems:] instead of opening the maps app via a URL in iOS 6. If you use a URL, you will not be able to pass "Current Location" and will lose the ability to do turn-by-turn navigation. MKMapItem has a specific item for current location that, when passed, will open Maps using Current Location as the source address thus enabling turn-by-turn navigation.

- (void)openMapsWithDirectionsTo:(CLLocationCoordinate2D)to {
    Class itemClass = [MKMapItem class];
    if (itemClass && [itemClass respondsToSelector:@selector(openMapsWithItems:launchOptions:)]) {
        MKMapItem *currentLocation = [MKMapItem mapItemForCurrentLocation];
        MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[[MKPlacemark alloc] initWithCoordinate:to addressDictionary:nil] autorelease]];
        toLocation.name = @"Destination";
        [MKMapItem openMapsWithItems:[NSArray arrayWithObjects:currentLocation, toLocation, nil]
                       launchOptions:[NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:MKLaunchOptionsDirectionsModeDriving, [NSNumber numberWithBool:YES], nil]
                                                                 forKeys:[NSArray arrayWithObjects:MKLaunchOptionsDirectionsModeKey, MKLaunchOptionsShowsTrafficKey, nil]]];
        [toLocation release];
    } else {
        NSMutableString *mapURL = [NSMutableString stringWithString:@"http://maps.google.com/maps?"];
        [mapURL appendFormat:@"saddr=Current Location"];
        [mapURL appendFormat:@"&daddr=%f,%f", to.latitude, to.longitude];
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[mapURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
    }
}


回答2:

I've used a preprocessor code like this one posted below to define my condition for the if cycle.

#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)

Then:

if (SYSTEM_VERSION_LESS_THAN(@"6.0")) {
         NSString* addr = [NSString stringWithFormat:@"http://maps.google.com/maps?daddr=%1.6f,%1.6f&saddr=Posizione attuale", view.annotation.coordinate.latitude,view.annotation.coordinate.longitude];
         NSURL* url = [[NSURL alloc] initWithString:[addr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
         [[UIApplication sharedApplication] openURL:url];
    }

else {
        NSString* addr = [NSString stringWithFormat:@"http://maps.apple.com/maps?daddr=%1.6f,%1.6f&saddr=Posizione attuale", view.annotation.coordinate.latitude,view.annotation.coordinate.longitude];
        NSURL* url = [[NSURL alloc] initWithString:[addr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
        [[UIApplication sharedApplication] openURL:url];


    }

It seems to work Bye !



回答3:

The accepted answer didn't work for me. The Current Location needs to be in the correct language and also the ios6 version didn't load correctly. For me the following worked.

NSString *destinationAddress = @"Amsterdam";

Class itemClass = [MKMapItem class];
if (itemClass && [itemClass respondsToSelector:@selector(openMapsWithItems:launchOptions:)]) {

    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder geocodeAddressString:destinationAddress completionHandler:^(NSArray *placemarks, NSError *error) {
        if([placemarks count] > 0) {

            MKPlacemark *placeMark = [[MKPlacemark alloc] initWithPlacemark:[placemarks objectAtIndex:0]];

            MKMapItem *mapItem = [[MKMapItem alloc]initWithPlacemark:placeMark];

            MKMapItem *mapItem2 = [MKMapItem mapItemForCurrentLocation];


            NSArray *mapItems = @[mapItem, mapItem2];

            NSDictionary *options = @{
        MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving,
        MKLaunchOptionsMapTypeKey:
            [NSNumber numberWithInteger:MKMapTypeStandard],
        MKLaunchOptionsShowsTrafficKey:@YES
            };

            [MKMapItem openMapsWithItems:mapItems launchOptions:options];

        } else {
            //error nothing found
        }
    }];
    return;
} else {

    NSString *sourceAddress = [LocalizedCurrentLocation currentLocationStringForCurrentLanguage];

    NSString *urlToOpen = [NSString stringWithFormat:@"http://maps.google.com/maps?saddr=%@&daddr=%@",
                 [sourceAddress stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
                 [destinationAddress stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlToOpen]];
}

For ios5 I use the LocalizedCurrentLocation from this post http://www.martip.net/blog/localized-current-location-string-for-iphone-apps

For ios6 I use the CLGeocoder to get the placemark and then open the map with it and the current location.

Remember to add CoreLocation.framework and MapKit.framework



回答4:

Swift 2.0 compatible.

I didn't find any exhaustive answer yet.

/**
Try to open google maps with navigation feature and with given coordinates

- parameter latitude:        destination latitude
- parameter longitude:       destination longitude
- parameter destinationName: destination name
- parameter completion:      completion callback
*/
static func openGoogleMapsNavigation(latitude: Double, longitude: Double, destinationName: String, completion: ((error: NSError?) -> (Void))?) {
    let directionRequest: MKDirectionsRequest = MKDirectionsRequest()
    let destination = Utils.createMapItem(name: destinationName, latitude: latitude, longitude: longitude)
    directionRequest.source = MKMapItem.mapItemForCurrentLocation()
    directionRequest.destination = destination
    directionRequest.transportType = MKDirectionsTransportType.Automobile
    directionRequest.requestsAlternateRoutes = true
    let directions: MKDirections = MKDirections(request: directionRequest)
    directions.calculateDirectionsWithCompletionHandler { (response: MKDirectionsResponse?, error: NSError?) -> Void in
        if error == nil {
            destination.openInMapsWithLaunchOptions([ MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving])
        }
        completion?(error: error)
    }
}

Where I have this utility method:

static func createMapItem(name name: String, latitude: Double, longitude: Double) -> MKMapItem {
    let coordinates = CLLocationCoordinate2DMake(latitude, longitude)
    let placemark = MKPlacemark(coordinate: coordinates, addressDictionary: nil)
    let mapItem = MKMapItem(placemark: placemark)
    mapItem.name = name
    return mapItem
}


回答5:

For people searching for an answer in swift -

 //MARK:- ViewDidLoad
         let directionRequest = MKDirectionsRequest()
                    directionRequest.source = self.sourceMapitem
                    directionRequest.destination = self.destinationMapitem
                    directionRequest.transportType = .Automobile
                // where sourceMapitem and destinationMapitem are MKMapItem     
                    let directions = MKDirections(request: directionRequest)
                    directions.calculateDirectionsWithCompletionHandler {
                        (response, error) -> Void in
                   if response != nil {
                        let route = response!.routes[0]
                        self.myMapView.addOverlay((route.polyline), level: MKOverlayLevel.AboveRoads)
                        print("OVER")
                    }
                        else{
                            print(" ERROR: \(error)")
                        }
                    }
        //MARK:- DefineFunctions
        func showRoute(response: MKDirectionsResponse) {

                for route in response.routes {

                    myMapView.addOverlay(route.polyline,
                                        level: MKOverlayLevel.AboveRoads)
                }
            }