Програмно відкрийте додаток Maps в iOS 6


159

Перед iOS 6 відкриття такої URL-адреси відкриє додаток (Google) Карти:

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

Тепер із новою реалізацією Apple Maps це відкриває мобільний Safari на Google Maps. Як я можу досягти такої ж поведінки з iOS 6? Як я можу програмно відкрити додаток Карти та вказати його на певне місце / адресу / пошук / що завгодно?

Відповіді:


281

Ось офіційний спосіб 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];
}

Якщо ви хочете отримати водіння або ходьбу інструкції до місця, ви можете включити mapItemForCurrentLocationз MKMapItemмасивом в +openMapsWithItems:launchOptions:, і встановити параметри запуску правильно.

// 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];
}

Після цього ви можете зберегти свій вихідний iOS 5 та нижчий код у elseвиписці if. Зауважте, що якщо ви скасуєте порядок елементів у openMapsWithItems:масиві, ви отримаєте вказівки від координати до поточного місця розташування. Ви, ймовірно, могли використовувати його, щоб отримати вказівки між будь-якими двома місцями, передавши побудований MKMapItemзамість поточного елемента карти розташування. Я цього не пробував.

Нарешті, якщо у вас є адреса (у вигляді рядка) , які ви хочете напрямок, використання геокодера щоб створити MKPlacemark, шляхом 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];

    }];
}

Код відмінно підходить для iOS 6. Варто зазначити, що якщо маршрут, який ми бажаємо, знаходиться від поточного місцезнаходження користувача до пункту призначення, тоді не потрібно проходити currentLocationMapItem.
Philip007

1
Той факт, що ви використовували координати
Томбуко,

+1 за те, що ви згадуєте, що це лише iOS 6 і що вам потрібен резервний запас
Генрік Ерландссон

2
як я можу перейти до мого поточного додатка з додатків карт?
Apple

1
Яке місце, яке я колись вибираю, коли він відкриває програму яблучних карт, він показує попередження "не вдалося знайти вказівки між цими місцями ios 6", а потім нічого не робити? Будь-яка допомога
NaXir

80

Знайшов відповідь на власне запитання. Apple , документує свою зіставляє формат URL тут . Схоже, ви можете по суті замінити maps.google.comїх maps.apple.com.

Оновлення. Виявляється, те саме стосується MobileSafari на iOS 6; торкніться посилання, щоб http://maps.apple.com/?q=...відкрити додаток Карти з цим пошуком, як http://maps.google.com/?q=...і в попередніх версіях. Це працює і задокументовано на сторінці, пов’язаній вище.

ОНОВЛЕННЯ: Це відповідає на моє запитання щодо формату URL. Але відповідь Неван Кінга тут (див. Нижче) - чудовий підсумок фактичного API Карт.


1
Цікаво. Якщо ви відкриєте браузер на maps.apple.com, він перенаправляє на maps.google.com. Цікаво, як довго це триватиме?
pir800

@ pir800 - Я насправді просто цікавився, що буде, якщо ви натиснете посилання на maps.apple.com в Safari на iOS 6. Я спробував це, і він переходить на Карти так само, як і в попередніх версіях iOS, коли ви натискали посилання на maps.google.com. Я думаю, що це гарно, що вони переспрямовують на карти Google, щоб автори веб-сайтів могли просто вказувати посилання на карту maps.apple.com і працювати з iOS на Картах, але нормально працювати на всіх інших клієнтах. Але я хотів би перевірити це якось перед тим, як змінити всі мої посилання на карту, щоб вказати на maps.apple.com!
Том Хеммінг

@ pir800 - для мене відкриття maps.apple.com у браузері переносить мене на apple.com/ios/maps . Можливо, мій попередній коментар бажано подумати.
Том Хеммінг

Я мав на увазі, якщо ви спробуєте запитати адресу або координувати. Спробуйте maps.apple.com/?q=los angeles, ca. Ви можете відкрити його на своєму настільному комп’ютері, і він перешле на сторінку maps.google.com
pir800

Чи є спосіб додати режим транзиту до цього запиту? (ходьба / їзда). не вдалося знайти жодної посилання на нього в Інтернеті.
Лірик

41

Найкращий спосіб зробити це - зателефонувати на новий метод iOS 6 MKMapItem openInMapsWithLaunchOptions:launchOptions

Приклад:

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];

Це запустить навігацію для руху з поточного місця.


1
Гаразд, то який найпростіший спосіб отримати екземпляр, MKMapItemколи я маю лише адресу? Цей API здається трохи складним для простого випадку використання.
Том Хеммінг

MKPlacemark * endLocation = [[MKPlacemark alloc] initWithCoordinate: nil addressDictionary: yourAdressDictHere]; ви можете передати адресу «Дикторія»
mariusLAN

7

Я бачу, ви знайшли URL-адресу maps.apple.com "схема". Це хороший вибір, оскільки він автоматично переспрямовує більш старі пристрої на maps.google.com. Але для iOS 6 є новий клас, яким ви можете скористатися: MKMapItem .

Два цікаві для вас методи:

  1. -openInMapsWithLaunchOptions: - викликайте його в екземплярі MKMapItem, щоб відкрити його в Maps.app
  2. + openMapsWithItems: launchOptions: - викликайте його в класі MKMapItem, щоб відкрити масив екземплярів MKMapItem.

Це виглядає корисно. Але це також здається трохи складнішим у використанні; Ви повинні мати init MKMapItemз MKPlacemark, який ви отримуєте, надаючи пару широти / довготи та словник адрес. Здається, просто відкрити http://maps.apple.com/?q=1+infinite+loop+cupertino+ca. Чи є перевага використовувати, MKMapItemколи все, що ви хочете зробити, це показати адресу в Картах?
Том Хеммінг

Вам не потрібно ініціалізувати, MKMapItemякщо ви вже не маєте посилання на той, який ви хочете використовувати. Просто використовуйте метод класу, +openMapsWithItems:launchOptions:на , MKMapItemщоб зробити те ж саме.
Марк Адамс

@MarkAdams цей метод класу містить масив екземплярів класу, так що так, йому потрібно мати хоча б один ініціалізований.
Філіп Раделіч

Тож у ситуації, коли у мене є відкриті координати GPS, але немає адреси, я використовую MKMapItemAPI, і він опускає крапку на карті з написом "Невідомо місце". Чи є спосіб отримати його для відображення назви для місцезнаходження? Я не бачу жодних клавіш для цього в параметрах адресного словника ...
Tom Hamming

5
@ Mr.Jefferson Встановіть властивість імені MKMapItem
matt

5

Ось клас із використанням рішення nevan king, завершеного в 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)
}

4

Мені прикро, що використання http://maps.apple.com?q= ... налаштування посилання відкриває браузер safari спочатку на старих пристроях.

Отже, для пристрою iOS 5, що відкриває ваш додаток із посиланням на maps.apple.com, такі дії виглядають так:

  1. ви натискаєте щось у програмі, і воно посилається на URL-адресу maps.apple.com
  2. safari відкриває посилання
  3. сервер maps.apple.com переспрямовує на URL-адресу maps.google.com
  4. тлумачить URL-адресу maps.google.com і відкриває додаток google Maps.

Я думаю, що (дуже очевидні та заплутані) кроки 2 та 3 дратують користувачів. Тому я перевіряю версію ОС і на пристрої запускаю maps.google.com або maps.apple.com (для респ. Ios 5 або ios 6 версій ОС).


Це я теж роблю. Здається, найкращий підхід.
Том Хеммінг

3

Мої дослідження з цього питання привели мене до таких висновків:

  1. Якщо ви використовуєте maps.google.com, вона відкриє карту в сафарі для кожного ios.
  2. Якщо ви використовуєте maps.apple.com, тоді вона відкриє карту в застосуванні карт ios 6, а також буде працювати з ios 5, а в ios 5 відкриє карту як звичайне в сафарі.

3

Якщо ви хочете натомість відкрити Карти Google (або запропонувати як додатковий варіант), ви можете використовувати схеми comgooglemaps://та comgooglemaps-x-callback://URL-адреси, задокументовані тут .


3

Перед запуском URL-адреси видаліть спеціальний символ із URL-адреси та замініть пробіли на +. Це позбавить вас від головних болів:

    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];
        }

2
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

Оновлено до Swift 4 на основі відповіді @ 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

Якщо не використовувати карти, а просто програматично виконувати дії UiButton, для мене це було чудово.

// 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!)

                }

Ви можете трохи поширити цей код. Наприклад, я поставив змінну як змінну рівня класу, мав іншу функцію заповнити її, а потім при натисканні на кнопку просто взяв те, що було в змінній, і вичищав її для використання в URL-адресі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.