天天看點

iOS開發—調用第三方地圖導航

項目裡面要求點選發送的位置,  需要導航, 導航兩種實作方式 (內建第三方SDK、URL跳轉第三方應用)  項目要求實作直接跳轉 是以接下來做的是實作URL跳轉第三方地圖來導航了

項目實作如下的效果:

iOS開發—調用第三方地圖導航

思路:傳入的目的地經緯度,再調用第三方的導航

第三方導航是指以URL跳轉的方式(在iOS中就是以URL Scheme的方式),直接跳到對應的地圖APP中,直接利用對方的功能來導航。這樣的優點,一是接入友善,二是不增加自己APP的開銷。缺點就是如果使用者沒有裝這個地圖,應用就沒辦法使用這個地圖的服務。但是蘋果有個自帶的高德地圖,像流氓軟體一樣,删也删不掉,是以說這個跳轉是能實作的。

接下來說一下我的實作

實作跳轉首先想到的肯定是配置URL Scheme 和白名單了

常用的4個地圖的 URL Scheme:

1.蘋果自帶地圖(不需要檢測,是以不需要URL Scheme)

2.百度地圖 :baidumap://

3.高德地圖 :iosamap://

4.谷歌地圖 :comgooglemaps://

注意:在  iOS 9 之後我們做跳轉是需要有個白名單的,添加白名單的方法就是在 info.plist 檔案裡面,添加一個字段LSApplicationQueriesSchemes  類型為數組,然後在這個數組裡面再添加我們所需要的地圖 URL Scheme :

iOS開發—調用第三方地圖導航

配置好白名單之後就要敲代碼了  如果沒有安裝某個地圖App  那麼對應的選項就不應該出現

想要檢測手機是否安裝了某個地圖APP,隻要調用下面這個方法就可以了:

[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"XXX://"]];
           

下面開始撸代碼:

第一:蘋果自帶地圖

蘋果提供了一種方式:MKMapItem(要使用記得導入

#import <MapKit/MapKit.h>

 頭檔案)

程式設計代碼:

//蘋果地圖
- (void)navAppleMap
{
    CLLocationCoordinate2D gps = _currentLocationCoordinate;
    
    MKMapItem *currentLoc = [MKMapItem mapItemForCurrentLocation];
    MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:gps addressDictionary:nil]];
    NSArray *items = @[currentLoc,toLocation];
    NSDictionary *dic = @{
                          MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeWalking,
                          MKLaunchOptionsMapTypeKey : @(MKMapTypeStandard),
                          MKLaunchOptionsShowsTrafficKey : @(YES)
                          }; 
    
    [MKMapItem openMapsWithItems:items launchOptions:dic];
}
           

其他第三方地圖,需要傳入經緯度:

Demo如下:

#pragma mark ----導航方法-----------

- (NSArray *)getInstalledMapAppWithEndLocation:(CLLocationCoordinate2D)endLocation
{
    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
    NSString *appName = [infoDictionary objectForKey:(NSString *)kCFBundleExecutableKey]; //擷取項目名稱
    NSMutableArray *maps = [NSMutableArray array];
    
    //蘋果地圖
    NSMutableDictionary *iosMapDic = [NSMutableDictionary dictionary];
    iosMapDic[@"title"] = @"蘋果地圖";
    [maps addObject:iosMapDic];
    
    //百度地圖
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"baidumap://"]]) {
        NSMutableDictionary *baiduMapDic = [NSMutableDictionary dictionary];
        baiduMapDic[@"title"] = @"百度地圖";
        NSString *urlString = [[NSString stringWithFormat:@"baidumap://map/direction?origin={{我的位置}}&destination=latlng:%f,%f|name=目的地&mode=walking&coord_type=gcj02",endLocation.latitude,endLocation.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        baiduMapDic[@"url"] = urlString;
        [maps addObject:baiduMapDic];
    }
       //高德地圖
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"iosamap://"]]) {
        NSMutableDictionary *gaodeMapDic = [NSMutableDictionary dictionary];
        gaodeMapDic[@"title"] = @"高德地圖";
        NSString *urlString = [[NSString stringWithFormat:@"iosamap://navi?sourceApplication=%@&backScheme=%@&lat=%f&lon=%f&dev=0&style=2",appName,APP_SCHEMES,endLocation.latitude,endLocation.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        gaodeMapDic[@"url"] = urlString;
        [maps addObject:gaodeMapDic];
    }
    
    //谷歌地圖
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"comgooglemaps://"]]) {
        NSMutableDictionary *googleMapDic = [NSMutableDictionary dictionary];
        googleMapDic[@"title"] = @"谷歌地圖";
        NSString *urlString = [[NSString stringWithFormat:@"comgooglemaps://?x-source=%@&x-success=%@&saddr=&daddr=%f,%f&directionsmode=walking",appName,@"nav123456",endLocation.latitude, endLocation.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        googleMapDic[@"url"] = urlString;
        [maps addObject:googleMapDic];
    }
    
    //騰訊地圖
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"qqmap://"]]) {
        NSMutableDictionary *qqMapDic = [NSMutableDictionary dictionary];
        qqMapDic[@"title"] = @"騰訊地圖";
        NSString *urlString = [[NSString stringWithFormat:@"qqmap://map/routeplan?from=我的位置&type=walk&tocoord=%f,%f&to=終點&coord_type=1&policy=0",endLocation.latitude, endLocation.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        qqMapDic[@"url"] = urlString;
        [maps addObject:qqMapDic];
    }
    
    return maps;
}
           

接着在點選導航調用的方法裡面,彈出提示框,設定代理方法:

- (void)navgationSender:(id)sender
{
    self.maps = [self getInstalledMapAppWithEndLocation:_currentLocationCoordinate];
    UIActionSheet *action = [[UIActionSheet alloc] init];
    for (NSDictionary *dic in self.maps) {
        [action addButtonWithTitle:[NSString stringWithFormat:@"%@", dic[@"title"]]];
    }
    [action addButtonWithTitle:@"取消"];
    action.cancelButtonIndex = self.maps.count;
    action.delegate = self;
    [action showInView:self.view];
    
}
#pragma mark UIActionSheetDelegate
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex != -1 && buttonIndex < self.maps.count) {
        if (buttonIndex == 0) {
            [self navAppleMap];
            return;
        }
        NSDictionary *dic = self.maps[buttonIndex];
        NSString *urlString = dic[@"url"];
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
    }
}
           

OK,可以調用第三方地圖啦!!!!!!!!

說一下注意事項:

1.引入頭檔案

#import <CoreLocation/CoreLocation.h>

#import <MapKit/MapKit.h>

2.傳參

一:百度地圖

NSString *urlString = [[NSString stringWithFormat:@"baidumap://map/direction?origin={{我的位置}}&destination=latlng:%f,%f|name=目的地&mode=walking&coord_type=gcj02",endLocation.latitude,endLocation.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
           

這裡面要注意幾點:

1,origin={{我的位置}}, 這個是不能被修改的,不然無法把出發位置設定為目前位置

2,destination = latlng:%f,%f|name = 目的地

這裡面的 name 的字段不能省略,否則導航會失敗,而後面的文字則可以随意

3,coord_type = gcj02

coord_type 允許的值為 bd09ll、gcj02、wgs84,如果你 APP 的地圖 SDK 用的是百度地圖 SDK,請填 bd09ll,否則就填gcj02,wgs84的話基本是用不上了(需要涉及到地圖加密)

二:高德地圖

NSString *urlString = [[NSString stringWithFormat:@"iosamap://navi?sourceApplication=%@&backScheme=%@&lat=%f&lon=%f&dev=0&style=2",appName,APP_SCHEMES,endLocation.latitude,endLocation.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
           

要注意幾點:

  1. sourceApplication=%@&backScheme=%@

    sourceApplication代表你自己APP的名稱,會在之後跳回的時候顯示出來,是以必須填寫。backScheme是你APP的URL Scheme,不填是跳不回來的

  2. dev=0

    這裡填0就行了,跟上面的gcj02一個意思 ,1代表wgs84, 也用不上。

繼續閱讀