iOS如何在VPN中進(jìn)行定位
App 在不使用外網(wǎng),只能連接 VPN(Virtual Private Network,即“虛擬專用網(wǎng)絡(luò)“)的情況下,通過訪問服務(wù)端提供的地址加載離線地圖。設(shè)備獲取當(dāng)前位置后,WKWebView 調(diào)用 JavaScript 定位函數(shù)并傳入經(jīng)緯度參數(shù),加載的地圖上浮現(xiàn)當(dāng)前定位點(diǎn)。
場景分析
針對(duì)以上場景,需要解決 iOS 如何在 VPN 中進(jìn)行定位的問題主要有以下兩點(diǎn):
- 使用第三方地圖平臺(tái)(如高德開放平臺(tái)、百度地圖開放平臺(tái)等)的解決方案無效,因?yàn)樵?VPN 環(huán)境中無法驗(yàn)證在地圖平臺(tái)申請(qǐng)的密鑰。
- iOS 自身獲取設(shè)備定位的方式有哪些。
iOS 系統(tǒng)定位方式
目前 iOS 設(shè)備的定位方式有基站定位、Wi-Fi 定位、GPS 定位。
基站定位
基本原理:每個(gè)基站都有一個(gè)標(biāo)識(shí)符,移動(dòng)設(shè)備能夠搜索周圍所有接收到信號(hào)的基站及其標(biāo)識(shí)符,通過聯(lián)網(wǎng)發(fā)送到蘋果云服務(wù)器,再由服務(wù)器根據(jù)這些基站的位置信息查詢并計(jì)算出當(dāng)前位置,返回手機(jī)。
iOS 優(yōu)化:蘋果將一部分重要基站(幾十公里選一個(gè))提前存儲(chǔ)在 iOS 系統(tǒng)中,這樣即便在無網(wǎng)環(huán)境下,也能定位到用戶的位置。
Wi-Fi 定位
基本原理:每個(gè)無線接入點(diǎn)(AP)都擁有各自的 MAC 地址,設(shè)備在開啟 Wi-Fi 的情況下,即可掃描并收集周圍的 AP 信號(hào)(不需要連接上,只需要接收到信號(hào)),獲取它們的 MAC 地址。設(shè)備將這些能夠標(biāo)識(shí) AP 的數(shù)據(jù)發(fā)送到服務(wù)器,服務(wù)器檢索出每個(gè) AP 的地理位置,并結(jié)合每個(gè)信號(hào)的強(qiáng)弱程度,計(jì)算出設(shè)備的地理位置并返回到設(shè)備。位置服務(wù)商需不斷更新、補(bǔ)充自己的數(shù)據(jù)哭,以保證數(shù)據(jù)的準(zhǔn)確性,畢竟無線 AP 會(huì)出現(xiàn)移動(dòng)的可能性。
iOS 優(yōu)化:iOS 設(shè)備在有網(wǎng)絡(luò)連接時(shí),會(huì)自動(dòng)下載所在地區(qū)周圍(幾個(gè)街區(qū)寬度或者更多)所有 Wi-Fi 熱點(diǎn)的信息到本地,這樣當(dāng)處于沒有網(wǎng)絡(luò)的情況下,iOS 照樣可以利用之前下載的熱點(diǎn)信息進(jìn)行定位。
GPS 定位
基本原理:利用天上衛(wèi)星(共24顆)進(jìn)行不斷廣播信號(hào),地面的 GPS 接收設(shè)備收到信號(hào)后,通過分析多個(gè)衛(wèi)星信號(hào),就可以計(jì)算出地球坐標(biāo)。GPS 保證大部分地區(qū)都可以同時(shí)收到至少4個(gè)衛(wèi)星信號(hào),從而可以精準(zhǔn)確定當(dāng)前的經(jīng)緯度以及海拔位置。
iOS 優(yōu)化:A-GPS
定位方式對(duì)照
iOS 定位實(shí)現(xiàn)方式
在 iOS 系統(tǒng)中實(shí)現(xiàn)定位用到的核心框架是 Core Location。
Core Location 提供確定設(shè)備的地理位置,高度,方向或相對(duì)于附近 iBeacon 的位置的服務(wù)。該框架使用所有可用的板載硬件,包括 Wi-Fi,GPS,藍(lán)牙,磁力計(jì),氣壓計(jì)和蜂窩硬件來收集數(shù)據(jù)。
由于定位服務(wù)涉及到用戶的地理位置信息,所以在 App 第一次調(diào)用定位服務(wù)時(shí)需要用戶對(duì)此進(jìn)行授權(quán)(授予或者拒絕該請(qǐng)求),系統(tǒng)會(huì)記錄用戶的回應(yīng),在以后的調(diào)用定位服務(wù)時(shí)不會(huì)在出現(xiàn)授權(quán)界面。當(dāng)然用戶可以手動(dòng)在應(yīng)用設(shè)置中修改權(quán)限,或者刪除應(yīng)用然后重新安裝進(jìn)行授權(quán)。
實(shí)現(xiàn) iOS 定位其實(shí)相對(duì)很簡單,主要使用定位框架中的 CLLocationManager 類,具體操作可以分為以下幾步:
1 添加核心框架的引用。
- #import
2 聲明 CLLocationManager 變量,添加需要實(shí)現(xiàn)定位服務(wù)的相關(guān)委托。
- @interface ViewController () {
- CLLocationManager *_locationManager;
- }
3 初始化和配置 CLLocationManager。
- // locaiton manager init
- _locationManager = [[CLLocationManager alloc] init];
- _locationManager.delegate = self;
- _locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
- _locationManager.distanceFilter = kCLDistanceFilterNone;
- // 請(qǐng)求權(quán)限
- [_locationManager requestAlwaysAuthorization];
- // 開始定位
- [_locationManager startUpdatingLocation];
這里主要講解下 desiredAccuracy 屬性和 distanceFilter 屬性,前者是用來控制定位精確程度,精確度越高耗電量越大,一般情況下 kCLLocationAccuracyBest 是最適合的選項(xiàng);后者是控制定位更新的頻率,單位是“米”,默認(rèn)情況下是 kCLDistanceFilterNone,即出現(xiàn)變化就通知。
另外在不需要定位服務(wù)的時(shí)候,可以調(diào)用 stopUpdatingLocation 方法來關(guān)閉定位更新,以達(dá)到節(jié)省電量的效果。
4 實(shí)現(xiàn) CLLocationManagerDelegate 委托方法。
- - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
- CLLocation *location = [locations lastObject];
- NSLog(@"locationManager:latitude:%f, longitude:%f", location.coordinate.latitude, location.coordinate.longitude);
- }
- - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
- NSLog(@"Error-Location: %@", error);
- }
火星坐標(biāo)
通過 WKWebView 將 iOS 定位獲取的經(jīng)緯度傳入前端 JavaScript 函數(shù)后,加載的離線地圖就會(huì)繪制當(dāng)前設(shè)備所在的位置。當(dāng)看著地圖上定位出現(xiàn)的圈圈時(shí),就像是吃著蘸了煉乳的烤面包一樣美味,只是放大看時(shí),發(fā)現(xiàn)在離線地圖上繪制的坐標(biāo)與實(shí)際坐標(biāo)會(huì)出現(xiàn)幾公里的誤差,無論如何調(diào)整定位參數(shù),誤差仍是存在。
通過查閱資料發(fā)現(xiàn)國內(nèi)大部分地圖因相關(guān)政策法規(guī)均存在偏移問題:
- 是一種國家保密插件,也叫做加密插件或者加偏或者 SM 模組,其實(shí)就是對(duì)真實(shí)坐標(biāo)系統(tǒng)進(jìn)行人為的加偏處理,按照特殊的算法,將真實(shí)的坐標(biāo)加密成虛假的坐標(biāo),而這個(gè)加偏并不是線性的加偏,所以各地的偏移情況都會(huì)有所不同。而加密后的坐標(biāo)也常被人稱為火星坐標(biāo)系統(tǒng)。
主要有如下 3 種標(biāo)準(zhǔn):
國內(nèi)準(zhǔn)許上市的地圖類產(chǎn)品都不是真實(shí)坐標(biāo)系統(tǒng),要想在其地圖上顯示正確的坐標(biāo),必須將獲取的定位轉(zhuǎn)換成它的坐標(biāo)系統(tǒng)?;旧细鱾€(gè)地圖平臺(tái)都提供相應(yīng)的坐標(biāo)轉(zhuǎn)換接口,通過轉(zhuǎn)化處理后加載的定位就是設(shè)備當(dāng)前的位置了。
Follow your heart.