上一回簡(jiǎn)單的介紹了一下 google map 的 SDK 的簡(jiǎn)單使用,但是光地圖的顯示實(shí)在是不夠用,顯示位置是地圖的基礎(chǔ),但是導(dǎo)航卻是地圖的核心,相信很多人會(huì)遇到地圖定位跟導(dǎo)航的問(wèn)題。那么這回我們就來(lái)簡(jiǎn)單講一下導(dǎo)航:
手機(jī)上的導(dǎo)航方式,分應(yīng)用內(nèi)導(dǎo)航和應(yīng)用外導(dǎo)航:
應(yīng)用內(nèi)導(dǎo)航
是指使用地圖服務(wù)提供的SDK(比如高德,百度等等),直接將導(dǎo)航功能嵌入到我們自己的APP內(nèi)部
但是這個(gè)方案我個(gè)人不喜歡,一是接入要一定的時(shí)間,二是增加APP的內(nèi)存占用。最最最最最最關(guān)鍵的問(wèn)題是難,難,難?。?!
應(yīng)用外導(dǎo)航
是以URI跳轉(zhuǎn)的方式(在iOS中就是以URL Scheme的方式),直接跳到對(duì)應(yīng)的地圖APP中,直接利用對(duì)方的功能來(lái)導(dǎo)航。
這樣的優(yōu)點(diǎn),一是接入方便,二是不增加自己APP的開(kāi)銷(xiāo);缺點(diǎn)就是如果用戶(hù)沒(méi)有裝這個(gè)地圖應(yīng)用就沒(méi)辦法使用這個(gè)地圖的服務(wù)。但是,可能你會(huì)說(shuō)萬(wàn)一他一個(gè)地圖的APP都沒(méi)有裝怎么辦?那不就實(shí)現(xiàn)不了了?
要相信蘋(píng)果不會(huì)讓你失望的,蘋(píng)果有個(gè)自帶的高德地圖,刪也刪不掉!這流氓,這時(shí)候還是管點(diǎn)用的。所以不用慌,就算他自己一個(gè)地圖類(lèi)的APP都不裝,那也有蘋(píng)果自帶的,所以肯定至少會(huì)有一個(gè),也就是說(shuō)這個(gè)跳轉(zhuǎn)是能實(shí)現(xiàn)的。
首先我們來(lái)看一下究竟是什么效果,你也可以自己下一個(gè)攜程旅游的APP(申明不是打廣告,因?yàn)槭巧匣啬硞€(gè)雷鋒告訴我的,攜程用的就是 google map),然后隨便選個(gè)酒店,點(diǎn)擊地圖,然后右上角導(dǎo)航,就是下面這效果:
當(dāng)然,如果沒(méi)有安裝某個(gè)地圖APP,那么對(duì)應(yīng)的選項(xiàng)是不會(huì)出現(xiàn)的。彈出來(lái)的這個(gè)AlertView大家自己去實(shí)現(xiàn),這里我就不多說(shuō)了。檢測(cè)APP是否安裝,只要調(diào)用下面這個(gè)方法就可以了:

比如你如果要檢測(cè)是否有安裝百度地圖APP,那么就是:
[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"baidumap://"]];
如果在這里寫(xiě)完代碼運(yùn)行的時(shí)候打印了一行錯(cuò)誤給你,那么看本文最后面,會(huì)有解決方法。
常用的4個(gè)地圖的 URL Scheme:
1.蘋(píng)果自帶地圖(不需要檢測(cè),所以不需要URL Scheme)
2.百度地圖 :baidumap://
3.高德地圖 :iosamap://
4.谷歌地圖 :comgooglemaps://
首先我們要開(kāi)啟定位功能,能定位到用戶(hù)的位置,這點(diǎn)相信大家都能實(shí)現(xiàn),就不多說(shuō)了。然后假設(shè)我們有一個(gè)終點(diǎn)的位置坐標(biāo):
CLLocationCoordinate2D loc = CLLocationCoordinate2DMake([self.model.latitude floatValue], [self.model.longitude floatValue]);
然后我們來(lái)實(shí)現(xiàn)跳轉(zhuǎn):
第一:蘋(píng)果自帶地圖
蘋(píng)果提供了另一種方式:MKMapItem(要使用記得導(dǎo)入#import <MapKit/MapKit.h> 頭文件)

代碼如下:
CLLocationCoordinate2D loc = CLLocationCoordinate2DMake([self.model.latitude floatValue], [self.model.longitude floatValue]);
MKMapItem *currentLocation = [MKMapItem mapItemForCurrentLocation];
MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:loc addressDictionary:nil]];
[MKMapItem openMapsWithItems:@[currentLocation, toLocation]
launchOptions:@{MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving,
MKLaunchOptionsShowsTrafficKey: [NSNumber numberWithBool:YES]}];
運(yùn)行效果如下,綠色大頭針是起點(diǎn)位置,紅色大頭針是終點(diǎn)位置:
第二:百度地圖
NSString *urlString = [[NSString stringWithFormat:@"baidumap://map/direction?origin={{我的位置}}&destination=latlng:%f,%f|name=目的地&mode=driving&coord_type=gcj02",coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
這里面要注意幾點(diǎn):
1,origin={{我的位置}}, 這個(gè)是不能被修改的,不然無(wú)法把出發(fā)位置設(shè)置為當(dāng)前位置
2,destination = latlng:%f,%f|name = 目的地
這里面的 name 的字段不能省略,否則導(dǎo)航會(huì)失敗,而后面的文字則可以隨意,賦個(gè)你的目的地的值給他就可以了。
3,coord_type = gcj02
coord_type 允許的值為 bd09ll、gcj02、wgs84,如果你 APP 的地圖 SDK 用的是百度地圖 SDK,請(qǐng)?zhí)?bd09ll,否則就填gcj02,wgs84的話(huà)基本是用不上了(需要涉及到地圖加密,有興趣的同學(xué)可以自己去了解)
效果如下:
最后兩種因?yàn)樽约菏謾C(jī)沒(méi)裝,沒(méi)試驗(yàn)過(guò),在網(wǎng)上找了下代碼,也貼出來(lái),需要用到的同學(xué)可以試一下,步驟都是一樣的。
高德地圖:
NSString *urlString = [[NSString stringWithFormat:@"iosamap://navi?sourceApplication=%@&backScheme=%@&lat=%f&lon=%f&dev=0&style=2",appName,urlScheme,coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
要注意幾點(diǎn):
- sourceApplication=%@&backScheme=%@
sourceApplication代表你自己APP的名稱(chēng) 會(huì)在之后跳回的時(shí)候顯示出來(lái) 所以必須填寫(xiě) backScheme是你APP的URL Scheme 不填是跳不回來(lái)的喲 - dev=0
這里填0就行了,跟上面的gcj02一個(gè)意思 1代表wgs84 也用不上
谷歌地圖:
NSString *urlString = [[NSString stringWithFormat:@"comgooglemaps://?x-source=%@&x-success=%@&saddr=&daddr=%f,%f&directionsmode=driving",appName,urlScheme,coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
要注意幾點(diǎn)
- x-source=%@&x-success=%@
跟高德一樣 這里分別代表APP的名稱(chēng)和URL Scheme - saddr=
這里留空則表示從當(dāng)前位置觸發(fā)。
OK,運(yùn)行一下,你會(huì)發(fā)現(xiàn),沒(méi)有跳轉(zhuǎn),而且還給你打印一串錯(cuò)誤!

瞬間覺(jué)得被作者坑了,莫慌。在 iOS 9 之后我們做跳轉(zhuǎn)是需要有個(gè)白名單的,就像我們做分享的時(shí)候也是一樣。
添加白名單:
在 info.plist 文件里面,添加一個(gè)字段:LSApplicationQueriesSchemes,類(lèi)型為數(shù)組,然后在這個(gè)數(shù)組里面再添加我們所需要的地圖 URL Scheme :
comgooglemaps
iosamap
comgooglemaps
效果如下:

OK,再也不用擔(dān)心坑爹的老板要我做導(dǎo)航了,你看別人家這么牛逼的都是做的跳轉(zhuǎn)的!簡(jiǎn)單輕松完成工作,而且用戶(hù)還能自己選擇自己喜歡的地圖。