當開發簡單的地圖功能時,我們可以使用集成地圖 SDK 來開發相應的功能,但是要開發導航這種復雜的功能時,我們就應該考慮一下專業的地圖應用了。而調用第三方地圖應用的正確姿勢是,只需要通過一個帶著導航參數的 URL 鏈接去打開第三方應用。即方法:
- (BOOL)openURL:(NSURL*)url ;
要進行跳轉需要先在 Xcode
的 info.plist
文件內將目標App的url Scheme
加入白名單(LSApplicationQueriesSchemes
)。
常見第三方地圖 App 的 url Scheme
百度地圖:baidumap
高德地圖:iosamap
騰訊地圖:qqmap
info.plist
的白名單設置:
在 plist
文件新增LSApplicationQueriesSchemes
關鍵字,類型為NSArray
,并在其下添加子目錄,類型為NSString
,內容為各地圖對應的url Scheme
。
url Scheme 配置
提供參數說明的官網地址:
高德地圖:URL Scheme: iosamap://
百度地圖:URL Scheme: baidumap://
騰訊地圖:URL Scheme: qqmap://
代碼實現:
為了方便調用,創建一個對象類來存儲地圖名稱和跳轉鏈接:
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface MapAppInfo : NSObject
@property (nonatomic, strong) NSString *appName;
@property (nonatomic, strong) NSString *mapUrl;
@end
NS_ASSUME_NONNULL_END
根據用戶已安裝的第三方導航應用來管理數據:
// 應用名稱
NSDictionary *dicInfo = [[NSBundle mainBundle] infoDictionary];
NSString *appName = dicInfo[@"CFBundleDisplayName"];
NSMutableArray *arrmTemp = [NSMutableArray arrayWithCapacity:100];
// 高德地圖
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"iosamap://"]]) {
MapAppInfo *mapInfo = [MapAppInfo new];
[mapInfo setAppName:@"高德地圖"];
NSMutableString *strmUrl = [NSMutableString stringWithFormat:@"iosamap://path?sourceApplication=%@", appName];
// 目的地
[strmUrl appendFormat:@"&dname=%@", @"深圳市民中心"];
// 目的地的火星坐標
[strmUrl appendFormat:@"&dlat=%@&dlon=%@", @"22.5", @"114.0"];
// t = 0(駕車)= 1(公交)= 2(步行)= 3(騎行)= 4(火車)= 5(長途客車)
[strmUrl appendFormat:@"&t=%@", @"2"];
[strmUrl appendFormat:@"&dev=0"];
mapInfo.mapUrl = strmUrl;
[arrmTemp addObject:mapInfo];
}
// 百度地圖
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"baidumap://"]]) {
MapAppInfo *mapInfo = [MapAppInfo new];
[mapInfo setAppName:@"百度地圖"];
NSMutableString *strmUrl = [NSMutableString stringWithFormat:@"baidumap://map/direction?"];
// 目的地名稱及火星坐標
[strmUrl appendFormat:@"destination=name:%@|latlng:%@,%@&", @"深圳市民中心", @"22.5", @"114.0"];
// 方式
[strmUrl appendFormat:@"mode=%@&", @"walking"];
// 火星坐標
[strmUrl appendFormat:@"coord_type=gcj02&"];
// 應用名稱
[strmUrl appendFormat:@"src=ios.%@", appName];
mapInfo.mapUrl = strmUrl;
[arrmTemp addObject:mapInfo];
}
// 騰訊地圖
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"qqmap://"]]) {
MapAppInfo *mapInfo = [MapAppInfo new];
[mapInfo setAppName:@"騰訊地圖"];
// 注:以我的位置為起點時,需要加入 “from=我的位置”,否則跳轉之后的起點位置為待輸入狀態
NSMutableString *strmUrl = [NSMutableString stringWithFormat:@"qqmap://map/routeplan?from=我的位置&"];
// 目的地
[strmUrl appendFormat:@"to=%@&", @"深圳市民中心"];
// 目的地的火星坐標
[strmUrl appendFormat:@"tocoord=%@,%@&", @"22.5", @"114.0"];
// 交通方式
[strmUrl appendFormat:@"type=%@&", @"walk"];
[strmUrl appendFormat:@"referer=%@", @"5ZABZ-6N4K5-F7EIZ-QUKIR-PC5IT-46BYM"];
mapInfo.mapUrl = strmUrl;
[arrmTemp addObject:mapInfo];
}
self.arrMapScheme = arrmTemp;
最后,在調用時,我們的起點和目的地由于使用了中文,所以需要發起調用的時候,將 URL 轉為 UTF-8
的格式:
NSString *strURL = self.arrMapScheme[0].mapUrl;
strURL = [strURL stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:strURL]];
[self cancelAction];
就是這樣了!