Programowo otwórz aplikację Maps w iOS 6

Poprzednio w iOS 6, otwarcie takiego adresu URL otworzyłoby aplikację (Google) Maps:

NSURL *url = [NSURL URLWithString:@"http://maps.google.com/?q=New+York"];
[[UIApplication sharedApplication] openURL:url];

Teraz z nową implementacją Apple Maps, to po prostu otwiera mobilne Safari do Google Maps. Jak mogę wykonać to samo zachowanie w systemie iOS 6? Jak programowo otworzyć aplikację Maps i wskazać konkretną lokalizację/adres/wyszukiwarkę / cokolwiek?

Author: nevan king, 2012-09-20

12 answers

Oto oficjalny sposób Apple:

// Check for iOS 6
Class mapItemClass = [MKMapItem class];
if (mapItemClass && [mapItemClass respondsToSelector:@selector(openMapsWithItems:launchOptions:)]) 
{
    // Create an MKMapItem to pass to the Maps app
    CLLocationCoordinate2D coordinate = 
                CLLocationCoordinate2DMake(16.775, -3.009);
    MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:coordinate 
                                            addressDictionary:nil];
    MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];
    [mapItem setName:@"My Place"];
    // Pass the map item to the Maps app
    [mapItem openInMapsWithLaunchOptions:nil];
}

Jeśli chcesz uzyskać instrukcje jazdy lub chodzenia do lokalizacji, możesz dołączyć mapItemForCurrentLocation z MKMapItem w tablicy w +openMapsWithItems:launchOptions: i odpowiednio ustawić opcje uruchamiania.

// Check for iOS 6
Class mapItemClass = [MKMapItem class];
if (mapItemClass && [mapItemClass respondsToSelector:@selector(openMapsWithItems:launchOptions:)]) 
{
    // Create an MKMapItem to pass to the Maps app
    CLLocationCoordinate2D coordinate = 
                CLLocationCoordinate2DMake(16.775, -3.009);
    MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:coordinate 
                                            addressDictionary:nil];
    MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];
    [mapItem setName:@"My Place"];

    // Set the directions mode to "Walking"
    // Can use MKLaunchOptionsDirectionsModeDriving instead
    NSDictionary *launchOptions = @{MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeWalking};
    // Get the "Current User Location" MKMapItem
    MKMapItem *currentLocationMapItem = [MKMapItem mapItemForCurrentLocation];
    // Pass the current location and destination map items to the Maps app
    // Set the direction mode in the launchOptions dictionary
    [MKMapItem openMapsWithItems:@[currentLocationMapItem, mapItem] 
                    launchOptions:launchOptions];
}
Możesz zachować oryginalny iOS 5 i niższy kod w instrukcji else po tym if. Zauważ, że jeśli odwrócisz kolejność elementów w tablicy openMapsWithItems:, otrzymasz wskazówki od współrzędnych do Twojej bieżącej lokalizacji. Mógłbyś prawdopodobnie użyje go do uzyskania kierunku pomiędzy dowolnymi dwoma lokalizacjami, przechodząc przez skonstruowaną MKMapItem zamiast aktualnej pozycji mapy lokalizacji. Nie próbowałem.

Na koniec, jeśli masz adres (jako ciąg znaków), do którego chcesz dotrzeć, użyj geokodera, aby utworzyć MKPlacemark, za pomocą CLPlacemark.

// Check for iOS 6
Class mapItemClass = [MKMapItem class];
if (mapItemClass && [mapItemClass respondsToSelector:@selector(openMapsWithItems:launchOptions:)])
{
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder geocodeAddressString:@"Piccadilly Circus, London, UK" 
        completionHandler:^(NSArray *placemarks, NSError *error) {

        // Convert the CLPlacemark to an MKPlacemark
        // Note: There's no error checking for a failed geocode
        CLPlacemark *geocodedPlacemark = [placemarks objectAtIndex:0];
        MKPlacemark *placemark = [[MKPlacemark alloc]
                                  initWithCoordinate:geocodedPlacemark.location.coordinate
                                  addressDictionary:geocodedPlacemark.addressDictionary];

        // Create a map item for the geocoded address to pass to Maps app
        MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];
        [mapItem setName:geocodedPlacemark.name];

        // Set the directions mode to "Driving"
        // Can use MKLaunchOptionsDirectionsModeWalking instead
        NSDictionary *launchOptions = @{MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving};

        // Get the "Current User Location" MKMapItem
        MKMapItem *currentLocationMapItem = [MKMapItem mapItemForCurrentLocation];

        // Pass the current location and destination map items to the Maps app
        // Set the direction mode in the launchOptions dictionary
        [MKMapItem openMapsWithItems:@[currentLocationMapItem, mapItem] launchOptions:launchOptions];

    }];
}
 281
Author: nevan king,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-17 16:57:03

Znalazłem odpowiedź na moje pytanie. Apple dokumentuje swój format URL map tutaj . Wygląda na to, że możesz zastąpić maps.google.com maps.apple.com.

Aktualizacja: okazuje się, że to samo jest prawdą w MobileSafari na iOS 6; stuknięcie linku do http://maps.apple.com/?q=... otwiera aplikację Maps z tym wyszukiwaniem, tak samo jak http://maps.google.com/?q=... w poprzednich wersjach. Działa to i jest udokumentowane na stronie podlinkowanej powyżej.

Aktualizacja: to odpowiada na moje pytanie dotyczące formatu URL. Ale nevan odpowiedź Kinga tutaj (patrz poniżej) jest doskonałym podsumowaniem rzeczywistego API Map.

 80
Author: Tom Hamming,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:43

Najlepszym sposobem na to jest wywołanie nowej metody iOS 6 na MKMapItem openInMapsWithLaunchOptions:launchOptions

Przykład:

CLLocationCoordinate2D endingCoord = CLLocationCoordinate2DMake(40.446947, -102.047607);
MKPlacemark *endLocation = [[MKPlacemark alloc] initWithCoordinate:endingCoord addressDictionary:nil];
MKMapItem *endingItem = [[MKMapItem alloc] initWithPlacemark:endLocation];

NSMutableDictionary *launchOptions = [[NSMutableDictionary alloc] init];
[launchOptions setObject:MKLaunchOptionsDirectionsModeDriving forKey:MKLaunchOptionsDirectionsModeKey];

[endingItem openInMapsWithLaunchOptions:launchOptions];

Spowoduje to uruchomienie nawigacji do jazdy z bieżącej lokalizacji.

 41
Author: zvonicek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-27 18:21:26

Widzę, że znalazłeś maps.apple.com url "schemat". Jest to dobry wybór, ponieważ automatycznie przekieruje starsze urządzenia do maps.google.com. ale dla iOS 6 jest nowa klasa, z której możesz skorzystać: MKMapItem .

Dwie interesujące Cię metody:

  1. - openInMapsWithLaunchOptions: - wywołaj go na instancji MKMapItem, aby otworzyć go w Mapach.app
  2. +openMapsWithItems: launchOptions: - wywołaj to na klasie MKMapItem do otwórz tablicę instancji MKMapItem.
 7
Author: Filip Radelic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-19 23:43:48

Oto Klasa wykorzystująca rozwiązanie nevan Kinga zakończone w języku Swift:

class func openMapWithCoordinates(theLon:String, theLat:String){

            var coordinate = CLLocationCoordinate2DMake(CLLocationDegrees(theLon), CLLocationDegrees(theLat))

            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)
}
 5
Author: PJeremyMalouf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-12 06:07:43

Irytuje mnie to, że używanie http://maps.apple.com?q = ... link setup otwiera najpierw przeglądarkę safari na starszych urządzeniach.

Więc dla urządzenia z systemem iOS 5 otwierającego Twoją aplikację z odniesieniem do maps.apple.com kroki wyglądają następująco:

  1. klikasz coś w aplikacji i odnosi się to do maps.apple.com url
  2. safari otwiera link
  3. the maps.apple.com serwer przekierowuje na maps.google.com url
  4. the maps.google.com URL zostanie zinterpretowany i otwiera aplikację Google Maps.

Myślę, że (bardzo oczywiste i mylące) kroki 2 i 3 są denerwujące dla użytkowników. Dlatego sprawdzam wersję systemu operacyjnego i uruchamiam maps.google.com lub maps.apple.com na urządzeniu (dla resp. wersje systemu operacyjnego IOS 5 lub iOS 6).

 4
Author: EeKay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-27 11:13:54

Moje badania na ten temat prowadzą mnie do następujących wniosków:

  1. Jeśli używasz maps.google.com następnie otworzy mapę w safari dla każdego ios.
  2. Jeśli używasz maps.apple.com następnie otworzy mapę w aplikacji map na ios 6, a także działa greate z ios 5, a w ios 5 otwiera mapę jak zwykle w safari.
 3
Author: Honey Jain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-01 09:01:54

Jeśli chcesz zamiast tego otworzyć Google Maps (lub zaoferować jako dodatkową opcję), możesz użyć schematów URL comgooglemaps:// i comgooglemaps-x-callback:// udokumentowanych tutaj .

 3
Author: Johan Kool,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-20 16:51:51

Przed uruchomieniem url Usuń dowolny znak specjalny z adresu url i zamień spacje na +. To zaoszczędzi ci bólów głowy:

    NSString *mapURLStr = [NSString stringWithFormat: @"http://maps.apple.com/?q=%@",@"Limmattalstrasse 170, 8049 Zürich"];

    mapURLStr = [mapURLStr stringByReplacingOccurrencesOfString:@" " withString:@"+"];
    NSURL *url = [NSURL URLWithString:[mapURLStr stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
    if ([[UIApplication sharedApplication] canOpenURL:url]){
            [[UIApplication sharedApplication] openURL:url];
        }
 3
Author: Javier Calatrava Llavería,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-07 10:41:55
NSString *address = [NSString stringWithFormat:@"%@ %@ %@ %@"
                             ,[dataDictionary objectForKey:@"practice_address"]
                             ,[dataDictionary objectForKey:@"practice_city"]
                             ,[dataDictionary objectForKey:@"practice_state"]
                             ,[dataDictionary objectForKey:@"practice_zipcode"]];


        NSString *mapAddress = [@"http://maps.apple.com/?q=" stringByAppendingString:[address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

        NSLog(@"Map Address %@",mapAddress);

        [objSpineCustomProtocol setUserDefaults:mapAddress :@"webSiteToLoad"];

        [self performSegueWithIdentifier: @"provider_to_web_loader_segue" sender: self];

/ / VKJ

 2
Author: Vinod Joshi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-08 06:40:19

Nie za pomocą Map, tylko programowo za pomocą działania UiButton, to działało świetnie dla mnie.

// Button triggers the map to be presented.

@IBAction func toMapButton(sender: AnyObject) {

//Empty container for the value

var addressToLinkTo = ""

//Fill the container with an address

self.addressToLinkTo = "http://maps.apple.com/?q=111 Some place drive, Oak Ridge TN 37830"

self.addressToLinkTo = self.addressToLinkTo.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!

let url = NSURL(string: self.addressToLinkTo)
UIApplication.sharedApplication().openURL(url!)

                }
Mógłbyś trochę rozłożyć ten kod. Na przykład, umieściłem zmienną jako zmienną poziomu klasy, miałem inną funkcję wypełnij go, a następnie po naciśnięciu przycisku po prostu wziął to, co było w zmiennej i szorował go do użycia w adresie URL.
 1
Author: Christopher Wade Cantley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-04 20:14:54

Zaktualizowano do Swift 4 na podstawie odpowiedzi @PJeremyMalouf:

private func navigateUsingAppleMaps(to coords:CLLocation, locationName: String? = nil) {
    let placemark = MKPlacemark(coordinate: coords.coordinate, addressDictionary:nil)
    let mapItem = MKMapItem(placemark: placemark)
    mapItem.name = locationName
    let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
    let currentLocationMapItem = MKMapItem.forCurrentLocation()

    MKMapItem.openMaps(with: [currentLocationMapItem, mapItem], launchOptions: launchOptions)
}
 1
Author: Chris Prince,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-30 22:43:14