2012-09-19 156 views
155

前到iOS 6,打开一个URL这样会打开(谷歌)地图应用:用新的苹果地图的实现在iOS的编程方式打开地图应用6

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

现在,这只是打开移动Safari浏览器谷歌地图。我如何才能完成与iOS 6相同的行为?如何以编程方式打开地图应用并使其指向特定位置/地址/搜索/任何内容?

回答

79

找到了我自己的问题的答案。苹果公司将其地图URL格式文件here。看起来你可以基本上用maps.apple.com代替maps.google.com

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

更新:这回答了我有关URL格式的问题。但是内文国王的回答here(见下文)是实际Maps API的极好摘要。

+1

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

+0

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

+0

@ pir800 - 对我来说,在浏览器中打开http://maps.apple.com会带我到http://www.apple.com/ios/maps/。也许我以前的评论是一厢情愿的想法。 –

7

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

两个方法,感兴趣的你:

  1. -openInMapsWithLaunchOptions: - 称之为上MKMapItem比如在Maps.app
  2. 打开它
  3. +openMapsWithItems:launchOptions: - 调用它MKMapItem类打开MKMapItem数组实例。
+0

看起来很有用。但它似乎使用起来更复杂一点;你必须用'MKPlacemark'来初始化'MKMapItem',你可以通过提供一个纬度/经度对和一个地址字典来获得它。似乎更简单,只需打开http://maps.apple.com/?q = 1 +无限+循环+ cupertino + ca'。当你想做的只是在地图中显示地址时,使用'MKMapItem'是否有优势? –

+0

如果您尚未引用您想要使用的引用,则不必初始化“MKMapItem”。只需在'MKMapItem'上使用类方法'+ openMapsWithItems:launchOptions:'来做同样的事情。 –

+0

@MarkAdams @类方法需要一个类的实例数组,所以是的,他需要至少有一个初始化。 –

41

做到这一点,最好的方法是调用新的iOS上MKMapItemopenInMapsWithLaunchOptions:launchOptions

例6方法:

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

好吧,那么获取' MKATAItem'当我所有的是一个地址?这个API对于那个简单的用例似乎有点复杂。 –

+0

MKPlacemark * endLocation = [[MKPlacemark alloc] initWithCoordinate:nil addressDictionary:yourAdDictDictHere]; 你可以在地址 – mariusLAN

+0

中递交地址Dictonary为我工作Xcode 6,iOS 8.0 – Jasmeet

4

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

所以对于iOS 5的设备打开你的应用程序有一个参考maps.apple.com的步骤是这样的:

  1. 您单击应用程序的东西,它是指maps.apple.com网址
  2. Safari浏览器打开该链接
  3. 的maps.apple.com服务器重定向到maps.google.com网址
  4. maps.google.com的URL被解释并打开谷歌地图应用。

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

+0

这就是我所做的。似乎是最好的方法。 –

3

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

  1. 如果使用maps.google.com,然后它会在Safari中打开地图为每部iOS。
  2. 如果您使用maps.apple.com,那么它将在ios 6的地图应用程序中打开地图,并且还会与ios 5一起工作,并在ios 5中以Safari浏览器的正常方式打开地图。
282

下面是苹果的官方途径:

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

如果你想获得驾车或步行指示的位置,可以包括在+openMapsWithItems:launchOptions:数组中的MKMapItem一个mapItemForCurrentLocation,并设置启动选项适当。

// 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和较低的代码在ifelse声明。请注意,如果您将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]; 

    }]; 
} 
+0

该代码适用于iOS 6。值得一提的是,如果我们想要的路由是从当前用户位置到目的地,那么不需要传入'currentLocationMapItem'。 – Philip007

+1

事实上,您使用Tombouctou坐标只是使答案更好:) – sachadso

+0

+1提及它只是iOS 6并且需要回退 –

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

5

下面是使用妮娃王的溶液中,斯威夫特完成了一个类:

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) 
} 
3

如果你想打开谷歌地图,而不是(或提供作为辅助选项),您可以使用comgooglemaps://comgooglemaps-x-callback:// URL scheme scheme here

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

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

更新斯威夫特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) 
} 
相关问题