objective-c 11 - 以編程方式在iOS 6中打開地圖應用程序




navigation bar (11)

在iOS 6之前,像這樣打開一個URL會打開(Google)地圖應用程序:

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

現在,隨著新的Apple Maps實施,這只是打開移動Safari到谷歌地圖。 我如何才能完成與iOS 6相同的行為? 如何以編程方式打開地圖應用並使其指向特定位置/地址/搜索/任何內容?


Answers

這是蘋果官方的方式:

// 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:中的數組中包含一個mapItemForCurrentLocation+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];
}

之後,您可以將原始iOS 5和更低代碼保留在else語句中。 請注意,如果您顛倒openMapsWithItems:數組中項目的順序,您將獲得從坐標當前位置的路線。 您可以通過傳遞構造的MKMapItem而不是當前的位置圖項來使用它來獲取任意兩個位置之間的方向。 我沒有嘗試過。

最後,如果你有一個你想要的地址(作為一個字符串),使用地理編碼器通過CLPlacemark創建一個MKPlacemark

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

    }];
}

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

最好的方法是在MKMapItem上調用新的iOS 6方法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];

這將開始從當前位置駕駛的導航。


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


我發現使用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網址會被解釋並打開Google地圖應用。

我認為(非常明顯且令人困惑)的步驟2和3對用戶來說很煩人。 因此,我檢查os版本,並在設備上運行maps.google.com或maps.apple.com(用於響應ios 5或ios 6操作系統版本)。


以下是使用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)
}

在啟動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];
        }

找到了我自己的問題的答案。 Apple here記錄其地圖URL格式。 看起來你基本上可以用maps.apple.com替換maps.google.com

更新:事實證明,iOS 6上的MobileSafari也是如此; 點擊鏈接http://maps.apple.com/?q=...使用該搜索打開地圖應用,方法與之前的http://maps.google.com/?q=...相同版本。 這工作,並記錄在上面鏈接的頁面。

更新:這回答了我有關URL格式的問題。 但是nevan king here的答案(見下文)是對實際Maps API的精彩總結。


如果您想改為打開Google地圖(或作為輔助選項提供),則可以使用comgooglemaps://comgooglemaps-x-callback:// URL方案。


我看到你找到了maps.apple.com url“scheme”。 這是一個不錯的選擇,因為它會自動將舊設備重定向到maps.google.com。 但是對於iOS 6,您可能想要利用以下新類: MKMapItem

您感興趣的兩種方法:

  1. -openInMapsWithLaunchOptions: - 在MKMapItem實例上調用它以在Maps.app中打開它
  2. +openMapsWithItems:launchOptions: - 在MKMapItem類上調用它打開一個MKMapItem實例數組。

將其複製到viewDidLoad中。 它將檢查iOS 5並使用首選方法,否則它將為navBar for iOS版本<5.0添加子視圖。 如果您的自定義背景圖像沒有透明度,這將有效。

float version = [[[UIDevice currentDevice] systemVersion] floatValue];
NSLog(@"%f",version);
UIImage *backgroundImage = [UIImage imageNamed:@"myBackgroundImage.png"];
if (version >= 5.0) {
    [self.navigationController.navigationBar setBackgroundImage:backgroundImage forBarMetrics:UIBarMetricsDefault];
}
else
{
    [self.navigationController.navigationBar insertSubview:[[[UIImageView alloc] initWithImage:backgroundImage] autorelease] atIndex:1];
}






ios objective-c ios6 mapkit