在iOS 6中以编程方式打开地图应用


159

在iOS 6之前的版本中,打开这样的URL将打开(Google)地图应用:

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

现在有了新的Apple Maps实施,这将打开Mobile Safari到Google Maps。如何使用iOS 6完成相同的行为?如何以编程方式打开“地图”应用,并使其指向特定的位置/地址/搜索/其他地方?

Answers:


281

这是苹果公司的官方方式:

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

如果要获取到该位置的驾驶或步行说明,可以mapItemForCurrentLocationMKMapItem中的阵列中添加+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];
}

之后,您可以在else语句中保留原始的iOS 5及更低版本的代码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];

    }];
}

该代码非常适合iOS6。值得一提的是,如果我们想要的路线是从当前用户位置到目的地,则无需传递currentLocationMapItem
Philip007

1
您使用Tombouctou坐标的事实只会使答案更好:)
sachadso

+1表示它仅适用于iOS 6,并且您需要后备广告
Henrik Erlandsson

2
如何从地图应用程序导航到当前应用程序?
苹果公司

1
我在打开Apple Maps App时选择的位置显示了警告“在这些位置ios 6之间找不到方向”,然后它什么也不做?任何帮助
NaXir 2013年

80

找到了我自己问题的答案。Apple 在此处记录其地图URL格式。看起来您基本上可以替换maps.google.commaps.apple.com

更新:事实证明,在iOS 6的MobileSafari中也是如此;点击链接以http://maps.apple.com/?q=...相同的方式打开带有该搜索的“地图”应用http://maps.google.com/?q=...以前版本。这有效并且记录在上面链接的页面中。

更新:这回答了我有关URL格式的问题。但是妮娃王的答案在这里(见下文)是实际的地图API的一个很好的总结。


1
有趣。如果您打开浏览器到maps.apple.com,它将重定向到maps.google.com。我想知道这能持续多久?
pir800 2012年

@ pir800-我实际上只是想知道如果您在iOS 6的Safari中点击指向maps.apple.com的链接会发生什么。我尝试了一下,当您点击时,它以与以前的iOS版本相同的方式进入Maps指向maps.google.com的链接。我认为这是一个很好的选择,他们将重定向到Google地图,以便网站作者可以将地图链接指向maps.apple.com,并使它在Maps中的iOS上正常运行,但在所有其他客户端上正常运行。但我想在更改所有地图链接以指向maps.apple.com之前以某种方式进行验证!
汤姆·汉明

@ pir800-对我来说,在浏览器中打开maps.apple.com会将我带到apple.com/ios/maps。也许我以前的评论是一厢情愿的。
汤姆·汉明

我的意思是,如果您尝试查询地址或坐标。请尝试maps.apple.com/?q=los洛杉矶。您可以在台式机上打开它,并将其转发到maps.google.com
pir800 2012年

有没有一种方法可以将过渡模式添加到该查询中?(步行/驾驶)。在网络上找不到任何引用。
Lirik 2013年

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:n addressDictionary:yourAdressDictHere]; 你可以在手ADRESS Dictonary
mariusLAN

7

我看到您找到了maps.apple.com网址“方案”。这是一个不错的选择,因为它将自动将较旧的设备重定向到maps.google.com。但是对于iOS 6,您可能想利用一个新类:MKMapItem

您感兴趣的两种方法:

  1. -openInMapsWithLaunchOptions: -在MKMapItem实例上调用它以在Maps.app中将其打开
  2. + openMapsWithItems:launchOptions: -在MKMapItem类上调用它以打开MKMapItem实例数组。

看起来很有用。但是使用起来似乎也有些复杂。你必须init MKMapItemMKPlacemark,通过提供纬度/经度对和一个地址字典来获得。似乎更容易打开http://maps.apple.com/?q=1+infinite+loop+cupertino+caMKMapItem当您只想在Google地图中显示地址时使用会不会有好处?
汤姆·汉明

MKMapItem如果尚未引用要使用的引用,则无需初始化。只需使用class方法,+openMapsWithItems:launchOptions:MKMapItem可以完成相同的操作。
Mark Adams

@MarkAdams该类方法接受一个类实例的数组,所以是的,他需要至少初始化一个。
Filip Radelic 2012年

因此,在我有要打开GPS坐标但没有地址的情况下,我使用MKMapItemAPI,它会在地图上标记为“未知位置”的点下降。有没有一种方法可以显示位置名称?我在地址字典的选项中没有看到任何按键...
汤姆·汉明

5
@ Mr.Jefferson设置MKMapItem的name属性
matt

5

这是使用在Swift中完成的nevan king解决方案的类:

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浏览器。

因此,对于通过引用maps.apple.com来打开您的应用的iOS 5设备,步骤如下:

  1. 您在应用程序中单击某些内容,它指向maps.apple.com网址
  2. 野生动物园打开链接
  3. maps.apple.com服务器重定向到maps.google.com网址
  4. maps.google.com网址将被解释并打开google Maps应用。

我认为第2步和第3步(非常明显且令人困惑)对用户来说很烦人。因此,我检查了操作系统版本,然后在设备上运行maps.google.com或maps.apple.com(对于ios 5或ios 6 OS版本)。


那也是我在做的。似乎是最好的方法。
汤姆·汉明

3

我对这个问题的研究得出以下结论:

  1. 如果您使用maps.google.com,它将为每个ios在safari中打开地图。
  2. 如果您使用maps.apple.com,则它将在ios 6的地图应用程序中打开地图,并且还可以在ios 5上正常工作;在ios 5中,它将在Safari中正常打开地图。

3

如果您想打开Goog​​le Maps(或作为辅助选项),则可以使用此处记录的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

根据@PJeremyMalouf的回答更新为Swift 4:

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中使用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.