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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12504294/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:14:54  来源:igfitidea点击:

Programmatically open Maps app in iOS 6

iosobjective-cios6mapkit

提问by Tom Hamming

Previous to iOS 6, opening a URL like this would open the (Google) Maps app:

在 iOS 6 之前,打开这样的 URL 将打开(谷歌)地图应用程序:

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

Now with the new Apple Maps implementation, this just opens Mobile Safari to Google Maps. How can I accomplish the same behavior with iOS 6? How do I programmatically open the Maps app and have it point to a specific location/address/search/whatever?

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

采纳答案by Tom Hamming

Found the answer to my own question. Apple documents its maps URL format here. It looks like you can essentially replace maps.google.comwith maps.apple.com.

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

Update:It turns out that the same is true in MobileSafari on iOS 6; tapping a link to http://maps.apple.com/?q=...opens the Maps app with that search, the same way http://maps.google.com/?q=...did on previous versions. This works and is documented in the page linked above.

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

UPDATE: This answers my question relating to the URL format. But nevan king's answer here(see below) is an excellent summary of the actual Maps API.

更新:这回答了我关于 URL 格式的问题。但是 nevan king在这里的回答(见下文)是对实际 Maps API 的一个很好的总结。

回答by nevan king

Here's the official Apple way:

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

If you want to get driving or walking instructions to the location, you can include a mapItemForCurrentLocationwith the MKMapItemin the array in +openMapsWithItems:launchOptions:, and set the launch options appropriately.

如果你想获得驾车或步行指示的位置,你可以包括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];
}

You can preserve your original iOS 5 and lower code in an elsestatement after that if. Note that if you reverse the order of items in the openMapsWithItems:array, you'll get directions from the coordinate toyour current location. You could probably use it to get directions between any two locations by passing a constructed MKMapIteminstead of the current location map item. I haven't tried that.

您可以在之后的else语句中保留原始的 iOS 5 和更低的代码if。请注意,如果您颠倒openMapsWithItems:数组中项目的顺序,您将获得从坐标当前位置的方向。您可以使用它通过传递构造的MKMapItem而不是当前位置地图项来获取任何两个位置之间的方向。我没试过。

Finally, if you have an address (as a string) that you want directions to, use the geocoder to create an MKPlacemark, by way of CLPlacemark.

最后,如果您有一个地址(作为一个字符串),您希望获得路线指引,请使用地理编码器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];

    }];
}

回答by zvonicek

The best way to do it is to call new iOS 6 method on MKMapItemopenInMapsWithLaunchOptions:launchOptions

最好的方法是调用新的 iOS 6 方法 MKMapItemopenInMapsWithLaunchOptions:launchOptions

Example:

例子:

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

This will start the navigation for driving from the current location.

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

回答by Filip Radelic

I see you found the maps.apple.com url "scheme". It's a good choice because it will automatically redirect older devices to maps.google.com. But for iOS 6 there is a new class you might want to take advantage of: MKMapItem.

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

Two methods that are of interest to you:

您感兴趣的两种方法:

  1. -openInMapsWithLaunchOptions:- call it on an MKMapItem instance to open it in Maps.app
  2. +openMapsWithItems:launchOptions:- call it on MKMapItem class to open an array of MKMapItem instances.
  1. -openInMapsWithLaunchOptions:- 在 MKMapItem 实例上调用它以在 Maps.app 中打开它
  2. +openMapsWithItems:launchOptions:- 在 MKMapItem 类上调用它以打开 MKMapItem 实例的数组。

回答by PJeremyMalouf

Here is a class using nevan king's solution completed in Swift:

这是一个使用 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)
}

回答by EeKay

I found it annoying that using the http://maps.apple.com?q=... link setup opens the safari browser first at older devices.

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

So for an iOS 5 device opening up your app with a reference to maps.apple.com the steps look like:

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

  1. you click something in the app and it refers to the maps.apple.com url
  2. safari opens up the link
  3. the maps.apple.com server redirects to the maps.google.com url
  4. the maps.google.com url gets interpreted and opens the google Maps app.
  1. 您单击应用程序中的某些内容,它指的是 maps.apple.com 网址
  2. safari 打开链接
  3. maps.apple.com 服务器重定向到 maps.google.com 网址
  4. maps.google.com url 被解释并打开谷歌地图应用程序。

I think that the (very obvious and confusing) steps 2 and 3 are annoying to users. Therefore i check the os version and either run maps.google.com or maps.apple.com on the device (for resp. ios 5 or ios 6 OS versions).

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

回答by Honey Jain

My research on this issue lead me to the following conclusions:

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

  1. If you use maps.google.com then it will open the map in safari for every ios.
  2. If you use maps.apple.com then it will open the map in map application of ios 6 and also work greate with ios 5 and in ios 5 it open the map as normal in safari.
  1. 如果您使用 maps.google.com,那么它将在 safari 中为每个 ios 打开地图。
  2. 如果您使用 maps.apple.com,那么它将在 ios 6 的地图应用程序中打开地图,并且在 ios 5 中也能很好地工作,而在 ios 5 中,它会在 safari 中正常打开地图。

回答by Johan Kool

If you want to open Google Maps instead (or offer as a secondary option), you can use the comgooglemaps://and comgooglemaps-x-callback://URL schemes documented here.

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

回答by Javier Calatrava Llavería

Before launching url, remove any special character from the url and replace spaces by +. This will save you some headaches:

在启动 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];
        }

回答by Chris Prince

Updated to Swift 4 based on @PJeremyMalouf's answer:

根据@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)
}