159

在 iOS 6 之前,打开这样的 URL 会打开 (Google) Maps 应用程序:

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

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

4

12 回答 12

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

如果您想获取到该位置的驾驶或步行指示,您可以在数组中包含 a 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];
}

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

    }];
}
于 2012-10-15T17:10:35.707 回答
80

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

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

更新:这回答了我关于 URL 格式的问题。但是 nevan king 的回答见下文)是对实际 Maps API 的出色总结。

于 2012-09-19T23:38:26.333 回答
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];

这将启动从当前位置驾驶的导航。

于 2012-09-22T15:05:11.313 回答
7

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

您感兴趣的两种方法:

  1. -openInMapsWithLaunchOptions: - 在 MKMapItem 实例上调用它以在 Maps.app 中打开它
  2. +openMapsWithItems:launchOptions: - 在 MKMapItem 类上调用它以打开 MKMapItem 实例数组。
于 2012-09-19T23:43:48.770 回答
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)
}
于 2014-11-12T06:07:43.293 回答
4

我发现使用http://maps.apple.com?q= ... 链接设置会首先在旧设备上打开 safari 浏览器,这很烦人。

因此,对于使用 maps.apple.com 参考打开您的应用程序的 iOS 5 设备,步骤如下所示:

  1. 您单击应用程序中的某些内容,它指的是 maps.apple.com 网址
  2. safari 打开链接
  3. maps.apple.com 服务器重定向到 maps.google.com url
  4. maps.google.com url 被解释并打开谷歌地图应用程序。

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

于 2012-09-27T10:46:28.873 回答
3

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

  1. 如果您使用 maps.google.com,那么它将在 Safari 中为每个 ios 打开地图。
  2. 如果您使用 maps.apple.com,那么它将在 ios 6 的地图应用程序中打开地图,并且还可以与 ios 5 一起使用,而在 ios 5 中,它会在 safari 中正常打开地图。
于 2012-10-01T07:57:18.013 回答
3

如果您想改为打开 Google 地图(或作为辅助选项提供),您可以使用此处comgooglemaps://记录的comgooglemaps-x-callback://URL 方案。

于 2015-01-20T16:51:51.653 回答
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];
        }
于 2016-07-07T10:41:55.073 回答
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

于 2013-11-08T06:40:19.140 回答
2

不使用地图,只是以编程方式使用 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 中使用。

于 2015-05-04T20:14:54.747 回答
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)
}
于 2017-09-30T22:43:14.627 回答