Buka aplikasi Maps secara terprogram di iOS 6

159

Sebelum iOS 6, membuka URL seperti ini akan membuka aplikasi (Google) Maps:

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

Sekarang dengan implementasi Apple Maps yang baru, ini hanya membuka Mobile Safari ke Google Maps. Bagaimana saya bisa mencapai perilaku yang sama dengan iOS 6? Bagaimana cara saya secara terprogram membuka aplikasi Maps dan mengarahkannya ke lokasi / alamat / pencarian tertentu / apa pun?

Tom Hamming
sumber

Jawaban:

281

Inilah cara resmi 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];
}

Jika Anda ingin mendapatkan instruksi mengemudi atau berjalan ke lokasi, Anda dapat memasukkan a mapItemForCurrentLocationdengan MKMapItemin the array in +openMapsWithItems:launchOptions:, dan mengatur opsi peluncuran dengan tepat.

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

Anda dapat menyimpan kode asli iOS 5 dan lebih rendah dalam elsepernyataan setelahnya if. Perhatikan bahwa jika Anda membalik urutan item dalam openMapsWithItems:array, Anda akan mendapatkan petunjuk arah dari koordinat ke lokasi Anda saat ini. Anda mungkin dapat menggunakannya untuk mendapatkan petunjuk arah antara dua lokasi mana pun dengan melewatkan MKMapItemitem peta yang dibuat alih-alih lokasi sekarang. Saya belum mencobanya.

Akhirnya, jika Anda memiliki alamat (sebagai string) yang Anda inginkan, gunakan geocoder untuk membuat MKPlacemark, dengan cara 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];

    }];
}
raja nevan
sumber
Kode berfungsi baik untuk iOS 6. Layak disebutkan jika jika rute yang kita inginkan adalah dari lokasi pengguna saat ini ke tujuan, maka tidak perlu untuk dilewati currentLocationMapItem.
Philip007
1
Fakta bahwa Anda menggunakan koordinat Tombouctou hanya membuat jawabannya lebih baik :)
sachadso
+1 untuk menyebutkan bahwa itu hanya iOS 6 dan Anda perlu mundur
Henrik Erlandsson
2
bagaimana cara saya menavigasi ke aplikasi saya saat ini dari aplikasi peta?
Apple
1
Lokasi apa yang saya pilih ketika membuka aplikasi peta apel yang menunjukkan peringatan "arah tidak dapat ditemukan antara lokasi-lokasi ini ios 6" dan kemudian tidak melakukan apa-apa? Any help
NaXir
80

Menemukan jawaban untuk pertanyaan saya sendiri. Apple mendokumentasikan format URL petanya di sini . Sepertinya pada dasarnya Anda dapat menggantinya maps.google.comdengan maps.apple.com.

Pembaruan: Ternyata hal yang sama berlaku di MobileSafari di iOS 6; mengetuk tautan untuk http://maps.apple.com/?q=...membuka aplikasi Maps dengan pencarian itu, seperti yang http://maps.google.com/?q=...dilakukan pada versi sebelumnya. Ini berfungsi dan didokumentasikan di halaman yang ditautkan di atas.

UPDATE: Ini menjawab pertanyaan saya yang berkaitan dengan format URL. Tapi jawaban raja nevan di sini (lihat di bawah) adalah ringkasan yang sangat baik dari Maps API yang sebenarnya.

Tom Hamming
sumber
1
Menarik. Jika Anda membuka peramban ke maps.apple.com, peralihan ke maps.google.com. Saya bertanya-tanya berapa lama ini akan berlangsung?
pir800
@ pir800 - Saya sebenarnya hanya bertanya-tanya tentang apa yang akan terjadi jika Anda mengetuk tautan ke maps.apple.com di Safari di iOS 6. Saya mencobanya, dan ia pergi ke Maps dengan cara yang sama seperti pada versi iOS sebelumnya ketika Anda mengetuk. tautan ke maps.google.com. Saya pikir ini adalah taruhan yang bagus bahwa mereka mengarahkan ulang ke peta Google sehingga penulis situs web dapat mengarahkan tautan peta ke maps.apple.com dan membuatnya bekerja di iOS di Maps tetapi bekerja secara normal pada semua klien lainnya. Tetapi saya ingin memverifikasi itu sebelum mengubah semua tautan peta saya ke arahkan ke maps.apple.com!
Tom Hamming
@ pir800 - bagi saya, membuka maps.apple.com di browser membawa saya ke apple.com/ios/maps . Mungkin komentar saya sebelumnya adalah angan-angan.
Tom Hamming
Maksud saya jika Anda mencoba untuk menanyakan alamat atau mengoordinasikan. Coba maps.apple.com/?q=los angeles, ca. Anda dapat membukanya di mesin desktop Anda dan itu akan meneruskan ke maps.google.com
pir800
Apakah ada cara untuk menambahkan mode transit ke kueri itu? (berjalan / mengemudi). tidak dapat menemukan referensi apa pun di web.
Lirik
41

Cara terbaik untuk melakukannya adalah dengan memanggil metode iOS 6 baru MKMapItem openInMapsWithLaunchOptions:launchOptions

Contoh:

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

Ini akan memulai navigasi untuk mengemudi dari lokasi saat ini.

zvonicek
sumber
1
OK, jadi apa cara termudah untuk mendapatkan contoh MKMapItemketika semua yang saya miliki adalah alamat? API ini tampaknya sedikit rumit untuk kasus penggunaan sederhana itu.
Tom Hamming
MKPlacemark * endLocation = [[Alokasi MKPlacemark] initWithCoordinate: nil addressDictionary: yourAdressDictHere]; Anda dapat menyerahkan alamat Dictonary di
mariusLAN
7

Saya melihat Anda menemukan url "skema" maps.apple.com. Ini adalah pilihan yang baik karena secara otomatis akan mengarahkan perangkat yang lebih lama ke maps.google.com. Tetapi untuk iOS 6 ada kelas baru yang mungkin ingin Anda manfaatkan: MKMapItem .

Dua metode yang menarik bagi Anda:

  1. -openInMapsWithLaunchOptions: - sebut saja pada instance MKMapItem untuk membukanya di Maps.app
  2. + openMapsWithItems: launchOptions: - sebut saja di kelas MKMapItem untuk membuka array instance MKMapItem.
Filip Radelic
sumber
Itu terlihat bermanfaat. Tetapi tampaknya juga sedikit lebih rumit untuk digunakan; Anda harus init MKMapItemdengan MKPlacemark, yang Anda dapatkan dengan menyediakan pasangan lintang / bujur dan kamus alamat. Tampaknya lebih mudah untuk dibuka http://maps.apple.com/?q=1+infinite+loop+cupertino+ca. Apakah ada keuntungan menggunakan MKMapItemketika semua yang ingin Anda lakukan adalah menunjukkan alamat di Maps?
Tom Hamming
Anda tidak harus menginisialisasi MKMapItemjika Anda belum memiliki referensi yang ingin Anda gunakan. Hanya menggunakan metode kelas, +openMapsWithItems:launchOptions:pada MKMapItemuntuk melakukan hal yang sama.
Mark Adams
@MarkAdams metode kelas mengambil array instance kelas ', jadi ya dia perlu memiliki setidaknya satu diinisialisasi.
Filip Radelic
Jadi dalam situasi ketika saya memiliki koordinat GPS untuk dibuka, tetapi tidak ada alamat, saya menggunakan MKMapItemAPI dan menjatuhkan titik pada peta yang berlabel "Lokasi Tidak Dikenal". Apakah ada cara untuk menampilkan nama lokasi? Saya tidak melihat kunci untuk ini dalam opsi untuk kamus alamat ...
Tom Hamming
5
@ Mr.Jefferson Tetapkan properti nama MKMapItem
matt
5

Ini adalah kelas yang menggunakan solusi nevan king yang diselesaikan di 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)
}
PJeremyMalouf
sumber
4

Saya merasa menjengkelkan karena menggunakan http://maps.apple.com?q= ... pengaturan tautan membuka browser safari terlebih dahulu di perangkat yang lebih lama.

Jadi untuk perangkat iOS 5 yang membuka aplikasi Anda dengan referensi maps.apple.com langkah-langkahnya terlihat seperti:

  1. Anda mengklik sesuatu di aplikasi dan itu merujuk ke url maps.apple.com
  2. safari membuka tautan
  3. server maps.apple.com mengalihkan ke url maps.google.com
  4. url maps.google.com ditafsirkan dan membuka aplikasi google Maps.

Saya pikir langkah (sangat jelas dan membingungkan) 2 dan 3 mengganggu pengguna. Karena itu saya memeriksa versi os dan menjalankan maps.google.com atau maps.apple.com pada perangkat (untuk resp. Ios 5 atau ios 6 versi OS).

EeKay
sumber
Itu yang saya lakukan juga. Sepertinya pendekatan terbaik.
Tom Hamming
3

Penelitian saya tentang masalah ini membawa saya pada kesimpulan berikut:

  1. Jika Anda menggunakan maps.google.com maka itu akan membuka peta di safari untuk setiap ios.
  2. Jika Anda menggunakan maps.apple.com maka itu akan membuka peta di aplikasi peta ios 6 dan juga bekerja greate dengan ios 5 dan di ios 5 itu membuka peta seperti biasa di safari.
Honey Jain
sumber
3

Jika Anda ingin membuka Google Maps saja (atau menawarkan sebagai opsi sekunder), Anda dapat menggunakan skema comgooglemaps://dan comgooglemaps-x-callback://URL yang didokumentasikan di sini .

Johan Kool
sumber
3

Sebelum meluncurkan url, hapus karakter khusus dari url dan ganti spasi dengan +. Ini akan menghemat beberapa sakit kepala:

    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];
        }
Javier Calatrava Llavería
sumber
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

Vinod Joshi
sumber
2

Diperbarui ke Swift 4 berdasarkan pada jawaban @ 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)
}
Chris Prince
sumber
1

Tidak menggunakan peta, hanya secara terprogram menggunakan tindakan UiButton, ini berhasil bagi saya.

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

                }

Anda dapat menyebarkan sedikit kode ini sedikit. Sebagai contoh, saya meletakkan variabel sebagai variabel tingkat kelas, memiliki fungsi lain mengisinya, dan kemudian ketika menekan tombol cukup mengambil apa yang ada dalam variabel dan menggosoknya untuk digunakan dalam URL.

Christopher Wade Cantley
sumber