關(guān)于iOS 應(yīng)用如何添加谷歌地圖龙考,網(wǎng)上其實(shí)有很多文檔愤炸,但當(dāng)自己實(shí)際開發(fā)時(shí)期揪,還是會(huì)有很多問題,我這次的需求就是地圖國(guó)際化规个,原項(xiàng)目中接的是高德地圖凤薛,現(xiàn)在要替換成谷歌地圖姓建,要求功能及頁(yè)面的UI顯示要和之前一致(肯定不可能百分百,至少8成像)
一枉侧、項(xiàng)目集成Google maps
官方文檔連接
推薦是使用cooapods集成引瀑,通常會(huì)使用一下兩個(gè)sdk
- 'GoogleMaps',基本的定位功能榨馁,通常加載這一個(gè)sdk就可以了
- 'GooglePlaces',實(shí)現(xiàn)搜索功能帜矾,官方文檔叫做地點(diǎn)自動(dòng)完成翼虫,可查找周圍的興趣點(diǎn),即POI
在Podfile添加
pod 'GoogleMaps', '指定版本號(hào)'
二屡萤、獲取API密匙
前提是已經(jīng)在GoogleMapSDK中創(chuàng)建好自己的應(yīng)用珍剑,需要有自己的Google賬號(hào),我這邊是Android開發(fā)早就申請(qǐng)好了死陆,我復(fù)制了APIKey直接使用
三招拙、配置plist文件搭建定位環(huán)境
info.pliste文件中添加定位權(quán)限相關(guān)字段
四、調(diào)用代理方法實(shí)現(xiàn)相關(guān)需求
- 在
AppDelegate.m
導(dǎo)入框架
#import <GoogleMaps/GoogleMaps.h>
- 在
application:didFinishLaunchingWithOptions
方法中添加
[GMSServices provideAPIKey: @"APIKey"];
- 在我們需要顯示地圖的控制器調(diào)用API方法
為了解耦代碼增加可復(fù)用性措译,可以寫一個(gè)地圖的類别凤,對(duì)地圖做一些簡(jiǎn)單的配置,增加一些自定義方法领虹,比如地圖截屏方法规哪,因?yàn)轫?xiàng)目的需求的是在一個(gè)IM空間中,像他人發(fā)送一個(gè)地理位置塌衰,以聊天氣泡的形式發(fā)送(參考微信中的“發(fā)送位置”)
簡(jiǎn)單介紹一下我用到的 GMSMapView
的屬性,如果想知道全部的屬性最疆,可以在地圖的sdk加載好之后杯巨,點(diǎn)擊進(jìn)入到 GMSMapView
中查看
- (GMSMapView *)mapView {
if (!_mapView) {
// 根據(jù)經(jīng)緯度和縮放等級(jí),初始化相機(jī)服爷,顯示地圖內(nèi)容镜会,用于海外的桶至,最好給個(gè)國(guó)外的經(jīng)緯度
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:38.8879
longitude:-77.0200
zoom:17];
_mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
_mapView.mapType = kGMSTypeNormal;
// 設(shè)備當(dāng)前位置的點(diǎn)和準(zhǔn)確性圓圈
_mapView.myLocationEnabled = YES;
// 使用指南針
_mapView.settings.compassButton = YES;
// 當(dāng)前位置按鈕
_mapView.settings.myLocationButton = YES;
_mapView.settings.indoorPicker = NO;
}
return _mapView;
}
- 需求1:大頭針和當(dāng)前位置的地址始終顯示在屏幕中間
這時(shí)候建議不要使用GMSMarker
价涝,因?yàn)樵趯?shí)際使用過(guò)程中,每當(dāng)移動(dòng)地圖居兆,大頭針會(huì)一跳一跳的簇宽,雖然也是一直顯示在最中間见妒,但是會(huì)有間歇性空白须揣,視覺效果不是很好卵酪,如果強(qiáng)行用GMSMarker
來(lái)定義大頭針,操作會(huì)很復(fù)雜瘸羡,不如直接定義一個(gè)UIImageView峻村,那對(duì)應(yīng)的詳細(xì)地址氣泡也需要自定義粘昨,最好寫個(gè)類,下面還有需求可以復(fù)用 - 需求2:地理位置反編譯工秩,本來(lái)是要顯示當(dāng)前位置的POI助币,但是
GMSMapView
沒有一個(gè)代理方法可以做到這一點(diǎn),只有點(diǎn)擊某個(gè)興趣點(diǎn)可以拿到那個(gè)興趣點(diǎn)的placeID惜姐,再根據(jù)placeID做其他操作坷衍,但是這不符合需求,需求是任意點(diǎn)都能拿到POI妻熊,如果任意點(diǎn)不是POI那就拿到最近的POI信息,這時(shí)候只引入GoogleMaps
的sdk已經(jīng)不能滿足需求了预皇,需要在 Podfile 中添加 'GooglePlaces'
pod 'GooglePlaces','指定版本號(hào)'
但是我實(shí)際使用過(guò)程中發(fā)現(xiàn)潘悼,還是不能滿足現(xiàn)在的需求,他的代理方法返回的是附近一些POI點(diǎn)的集合榄檬,一個(gè)數(shù)組衔统,而且測(cè)試發(fā)現(xiàn)鹿榜,這個(gè)數(shù)組中的元素,只是你當(dāng)前設(shè)備所在位置周邊的POI的信息锦爵,不是隨著你地圖中心位置移動(dòng)而變化的舱殿,達(dá)不到想要的效果(也許還有其他方法我沒發(fā)現(xiàn),有經(jīng)驗(yàn)的大佬請(qǐng)教教我)险掀,最后退而求其次沪袭,用了 GMSAddress
,對(duì)當(dāng)前經(jīng)緯度的位置做了反編譯樟氢,做多能拿到當(dāng)前位置是那條路和郵編冈绊。
提示: GMSServices 和 GMSPlacesClient 的 APIKey是不同的侠鳄,不能使用同一個(gè),
[GMSServices provideAPIKey: @"key1"];
[GMSPlacesClient provideAPIKey: @"key2"];
否則 GooglePlaces 里面類的代理方法使用都會(huì)報(bào)錯(cuò)Error Domain=com.google.places.ErrorDomain Code=-3 "An internal error occurred in the Places API library. If you believe this error represents a bug, please file a report using the instructions on our community and support page ([https://developers.google.com/places/ios-sdk/support)](https://developers.google.com/places/ios-sdk/support))." UserInfo={NSLocalizedFailureReason=An internal error occurred in the Places API library. If you believe this error represents a bug, please file a report using the instructions on our community and support page ([https://developers.google.com/places/ios-sdk/support).](https://developers.google.com/places/ios-sdk/support).), NSUnderlyingError=0x171251c10 {Error Domain=com.google.places.api.server.ErrorDomain Code=-2 "This API project is not authorized to use this API." UserInfo={NSLocalizedFailureReason=This API project is not authorized to use this API.}}}
- 需求三3:別人點(diǎn)開我發(fā)送給他的位置死宣,要求地圖可滑動(dòng)縮放伟恶,但是我發(fā)送的位置處會(huì)有大頭針及地址氣泡,并且位置固定在對(duì)應(yīng)的經(jīng)緯度毅该,這就和需求1又不一樣了博秫,這時(shí)候最方便的就是用sdk中的大頭針
GMSMarker
并且自定義大頭針氣泡,在下面這個(gè)代理方法中寫視圖
- (nullable UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker;
五眶掌、遇到的問題
- 當(dāng)他人查看我送的位置時(shí)挡育,一進(jìn)入到該頁(yè)面要求大頭針氣泡是始終顯示的,這就需要將地圖的
selectedMarker
設(shè)為當(dāng)前的大頭針朴爬,因?yàn)榈貓D可縮放滑動(dòng)即寒,當(dāng)點(diǎn)擊到地圖任意一點(diǎn),大頭針氣泡都會(huì)隱藏召噩,我這邊是在didTapAtCoordinate
方法中設(shè)置地圖的selectedMarker
- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate {
self.mapView.selectedMarker = self.defaultMarker;
}
- 打開地圖蒿叠,將地圖中心點(diǎn)移到很遠(yuǎn)的地方,大概5分鐘左右蚣常,地圖中心點(diǎn)會(huì)在自動(dòng)回到當(dāng)前設(shè)備所在位置,
處理方法:我是將 CLLocationManager 的distanceFilter
屬性設(shè)置成默認(rèn)的痊银,感覺是可以的抵蚊,我自測(cè)沒什么問題,具體我也不清楚溯革,等待測(cè)試反饋結(jié)果贞绳。