iOS定位服務(wù)

最近在做公司內(nèi)部的一個(gè)項(xiàng)目哀峻。主要需求很簡(jiǎn)單哟绊,就是每隔N分鐘向服務(wù)器發(fā)送設(shè)備的位置,不管此時(shí)App是運(yùn)行在前臺(tái)還是后臺(tái)钠导。
這里總結(jié)一下使用iOS定位服務(wù)的一些關(guān)鍵點(diǎn)和需要注意的地方坐梯。

App 的設(shè)置

  1. 因?yàn)锳pp需要在后臺(tái)的時(shí)候也能不斷地獲取設(shè)備的位置徽诲。所以要將Capablities里面的BackgroundMode 設(shè)置成Enable。并且勾選其中的Location updates選項(xiàng)吵血。
  2. 在iOS8以后谎替,需要在info.plist里面添加NSLocationAlwaysUsageDescription或者NSLocationWhenInUseUsageDescription,這兩個(gè)key都是NSString類型。使用哪個(gè)(或者兩者都添加)取決于申請(qǐng)定位的權(quán)限蹋辅,這個(gè)下文會(huì)提到钱贯。這個(gè)所謂的描述就是當(dāng)系統(tǒng)提示用戶App要使用定位的時(shí)候,會(huì)加在系統(tǒng)提示的后面侦另,如圖秩命。

初始化CLLocationManager

使用iOS定位服務(wù)需要引入系統(tǒng)的頭文件并且實(shí)現(xiàn)CLLocationManagerDelegate的代理。

    #import <CoreLocation/CoreLocation.h>

先來看一下初始化的代碼:

-(void) createLocationManager{
    _locationManager = [[CLLocationManager alloc] init];
    _locationManager.delegate = self;
    if ([_locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
        [_locationManager requestAlwaysAuthorization];
    }
    if ([_locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
        [_locationManager setAllowsBackgroundLocationUpdates:YES];
    }
    _locationManager.pausesLocationUpdatesAutomatically = NO;
}

iOS8以后褒傅,系統(tǒng)的定位權(quán)限有三種弃锐,對(duì)應(yīng)設(shè)置里面的總是,永不殿托,和App使用期間霹菊。那么根據(jù)我們App的需求,我們需要申請(qǐng)“總是”這種權(quán)限支竹。相應(yīng)地旋廷,我們要在info.plist里面添加的是NSLocationAlwaysUsageDescription鸠按。

    if ([_locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
       [_locationManager requestAlwaysAuthorization];
    }

并且在iOS9之后,如果需要在后臺(tái)保持定位,除了上文所說的在App的setting和info文件里面設(shè)置以外柳洋,還需要加上下面的代碼:

if ([_locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
    [_locationManager setAllowsBackgroundLocationUpdates:YES];
}

整個(gè)初始化完成以后待诅,調(diào)用以下API系統(tǒng)就會(huì)開始定位了

[_locationManager startUpdatingLocation];

在代理里面實(shí)現(xiàn)位置更新的代碼

正常來說,完成上面的所有設(shè)置熊镣,就可以使用iOS系統(tǒng)的定位服務(wù)了。
系統(tǒng)會(huì)每秒都調(diào)用

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations

這個(gè)代理方法募书,我們所要做的就是在這里處理系統(tǒng)返回回來的位置信息绪囱。
CLLocation這個(gè)類里面包括的一些常用的位置信息有經(jīng)度、緯度莹捡、海拔鬼吵、速度、精確度等等篮赢,根據(jù)項(xiàng)目的需求可以對(duì)其進(jìn)行相應(yīng)的處理齿椅。

到這里,最基礎(chǔ)的部分已經(jīng)完成启泣。接下來會(huì)探討一些別的配置涣脚。

pausesLocationUpdatesAutomatically屬性

貼上一段官網(wǎng)對(duì)這個(gè)屬性的描述:

Allowing the location manager to pause updates can improve battery life on the target device without sacrificing location data. When this property is set to YES, the location manager pauses updates (and powers down the appropriate hardware) at times when the location data is unlikely to change. For example, if the user stops for food while using a navigation app, the location manager might pause updates for a period of time. You can help the determination of when to pause location updates by assigning a value to the activityTypeproperty.

大致的意思就是如果這個(gè)屬性設(shè)置成YES(默認(rèn)的也是YES),那么系統(tǒng)會(huì)檢測(cè)如果設(shè)備有一段時(shí)間沒有移動(dòng)寥茫,就會(huì)自動(dòng)停掉位置更新服務(wù)遣蚀。這里需要注意的是,一旦定位服務(wù)停止了纱耻,只有當(dāng)用戶再次開啟App的時(shí)候定位服務(wù)才會(huì)重新啟動(dòng)芭梯。
這里的一段時(shí)間是系統(tǒng)自動(dòng)判定的,可以通過設(shè)置activityTypeproperty這個(gè)屬性來決定這個(gè)時(shí)間的長(zhǎng)短弄喘。
API的意思是玖喘,類似導(dǎo)航類的App,系統(tǒng)檢驗(yàn)的時(shí)間會(huì)稍長(zhǎng)一點(diǎn),想運(yùn)動(dòng)類的App蘑志,就會(huì)比導(dǎo)航類的短一點(diǎn)累奈。但是具體時(shí)間還是由系統(tǒng)來決定。

DeferredUpdates

默認(rèn)地卖漫,定位服務(wù)的代理會(huì)每秒鐘都更新一次位置费尽,這樣對(duì)電池的消耗量會(huì)特別地大。除了設(shè)置pausesLocationUpdatesAutomatically這個(gè)屬性以外羊始,iOS還提供了DeferredUpdates的機(jī)制旱幼。

官方API文檔:

- (void)allowDeferredLocationUpdatesUntilTraveled:(CLLocationDistance)distance
                                      timeout:(NSTimeInterval)timeout

distance:
The distance (in meters) from the current location that must be travelled before event delivery resumes. To specify an unlimited distance, pass the CLLocationDistanceMaxconstant.

timeout:
The amount of time (in seconds) from the current time that must pass before event delivery resumes. To specify an unlimited amount of time, pass the CLTimeIntervalMax constant.

就是你可以設(shè)置讓系統(tǒng)每隔多遠(yuǎn)或者每隔多長(zhǎng)時(shí)間更新一次位置。注意是“或”的關(guān)系突委,滿足一個(gè)就會(huì)更新柏卤。
使用這個(gè)方法有很多要注意的地方:

  1. desiredAccuracy必須設(shè)置成kCLLocationAccuracyBest
  2. distanceFilter必須設(shè)置成kCLErrorDeferredDistanceFiltered
  3. 必須能夠使用GPS進(jìn)行定位(而不僅僅是移動(dòng)數(shù)據(jù)或者Wi-Fi)
  4. 非常重要的一點(diǎn)冬三,DeferredUpdates只會(huì)出現(xiàn)在設(shè)備進(jìn)入低耗電量的狀態(tài),App運(yùn)行在前臺(tái)或者設(shè)備連接在Xcode上正在調(diào)試是不會(huì)觸發(fā)的缘缚。(所以不可能在Debug的時(shí)候打印Log來檢驗(yàn)勾笆,要調(diào)試的話,需要寫一些Log存在本地的數(shù)據(jù)庫)

官網(wǎng)的Example:

-(void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
  // Add the new locations to the hike
  [self.hike addLocations:locations];
 
  // Defer updates until the user hikes a certain distance or a period of time has passed
  if (!self.deferringUpdates) {
    CLLocationDistance distance = self.hike.goal - self.hike.distance;
    NSTimeInterval time = [self.nextUpdate timeIntervalSinceNow];
    [self.locationManager allowDeferredLocationUpdatesUntilTraveled:distance timeout:time];
    self.deferringUpdates = YES;
  } }
 
-(void)locationManager:(CLLocationManager *)manager
    didFinishDeferredUpdatesWithError:(NSError *)error {
  // Stop deferring updates
  self.deferringUpdates = NO;
 
  // Adjust for the next goal
}

反地理編碼

知道了經(jīng)緯度桥滨,有時(shí)候我們需要獲取這個(gè)經(jīng)緯度對(duì)應(yīng)的詳細(xì)地址信息窝爪,示例如下:

CLGeocoder *revGeo = [[CLGeocoder alloc] init];
[revGeo reverseGeocodeLocation:location
                 completionHandler:^(NSArray *placemarks, NSError *error) {
                     if (!error && [placemarks count] > 0)
                     {
                         NSDictionary *dict =
                         [[placemarks objectAtIndex:0] addressDictionary];
                         NSArray *formattedLines = [dict objectForKey:@"FormattedAddressLines"];
                         NSString *formattedAddress = formattedLines[0];
                         NSLog(@"address is %@",formattedAddress);
                     }else{
                         NSLog(@"ERROR: %@", error);
                     }
                 }];

關(guān)于坐標(biāo)系的問題

最后講一下關(guān)于坐標(biāo)系的問題。
世界通用的坐標(biāo)系是WGS坐標(biāo)系齐媒,中國國測(cè)局的坐標(biāo)系是GCJ蒲每,百度有自己的坐標(biāo)系。
同樣的經(jīng)緯度應(yīng)用在不同的坐標(biāo)系會(huì)有所偏差喻括,在Github上面有一個(gè)庫可以實(shí)現(xiàn)不同坐標(biāo)系之間的轉(zhuǎn)化:
https://github.com/TinyQ/TQLocationConverter
系統(tǒng)返回的自然是根據(jù)WGS定位的邀杏。如果使用百度SDK獲取的就是Baidu坐標(biāo)系的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末唬血,一起剝皮案震驚了整個(gè)濱河市望蜡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拷恨,老刑警劉巖脖律,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異挑随,居然都是意外死亡状您,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門兜挨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來膏孟,“玉大人,你說我怎么就攤上這事拌汇∑馍#” “怎么了?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵噪舀,是天一觀的道長(zhǎng)魁淳。 經(jīng)常有香客問我,道長(zhǎng)与倡,這世上最難降的妖魔是什么界逛? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮纺座,結(jié)果婚禮上息拜,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好少欺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布喳瓣。 她就那樣靜靜地躺著,像睡著了一般赞别。 火紅的嫁衣襯著肌膚如雪畏陕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天仿滔,我揣著相機(jī)與錄音惠毁,去河邊找鬼。 笑死堤撵,一個(gè)胖子當(dāng)著我的面吹牛仁讨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播实昨,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼盐固!你這毒婦竟也來了荒给?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤刁卜,失蹤者是張志新(化名)和其女友劉穎志电,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛔趴,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挑辆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了孝情。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鱼蝉。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖箫荡,靈堂內(nèi)的尸體忽然破棺而出魁亦,到底是詐尸還是另有隱情,我是刑警寧澤羔挡,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布洁奈,位于F島的核電站,受9級(jí)特大地震影響绞灼,放射性物質(zhì)發(fā)生泄漏利术。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一低矮、第九天 我趴在偏房一處隱蔽的房頂上張望贤惯。 院中可真熱鬧,春花似錦春感、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肠虽。三九已至幔戏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間税课,已是汗流浹背闲延。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留韩玩,地道東北人垒玲。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像找颓,于是被迫代替她去往敵國和親合愈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容