iOS 後臺定位 藍條問題

首先對於定位功能實現的問題,詳見這幅帖子,超級全面詳細:【iOS】7.4 定位服務->2.1.2 定位 - 官方框架CoreLocation: CLLocationManager(位置管理器)bash

1、開啓定位權限的配置

iOS定位權限自從iOS8以後就改動不少,出於對用戶隱私方面來講,若是要調用GPS模塊,就必須通過用戶肯定,體如今應用彈窗讓用戶選擇。須要在info.plist文件添加3個受權app

  • a. Privacy - Location When In Use Usage Description (應用使用期間),
  • b. Privacy - Location Always Usage Description(始終容許),
  • c. Privacy - Location Always and When In Use Usage Description(始終容許,iOS11新增)
在iOS11時,Privacy - Location Always and When In Use Usage Description表示始終容許,Location Always Usage Description在功能上被降級爲爲「應用使用期間」。
複製代碼

若是a,b兩項添加到plist裏,受權提示有2個選擇項框架

定位受權彈窗一
若是a,b,c 所有添加到plist裏,受權提示有3個選擇項

定位受權彈窗二

那麼當咱們容許應用使用GPS獲取位置信息以後,咱們在設置-隱私-定位服務 找到本身的應用點進去能夠看到以下 upload-images.jianshu.io/upload_imag… ui

有三個選項: 1.永不 2.使用應用期間 3.始終。spa

  • 永不:不給定位權限
  • 使用應用期間:應用在前臺運行狀態才獲取定位信息
  • 始終:包括應用在後臺也能獲取定位信息

通常狀況下,在info.plist文件中,將以上三條都配置上.code

固然,有的狀況下只需兩個選擇:cdn

  • 1.永不 2.使用應用期間
    info.plist只設置了NSLocationWhenInUseUsageDescription對象

  • 1.永不 2.始終blog

    info.plist只設置了NSLocationAlwaysUsageDescription和NSLocationAlwaysAndWhenInUseUsageDescription (今天在iPhone7 plus iOS12.1.4系統 怎麼試都不顯示定位選擇彈框,不知道咋回事,大家能夠嘗試下,告知下我結果)。ip

通常除了導航、運動類App纔會用到

2、實現後臺定位

對於一些運動類、導航類App,可能計時應用退到了後臺也要獲取用戶的位置信息,該功能的實現咱們姑且稱爲:後臺定位。

首先,在TARGETS->Capabilities->Background Modes中,開啓開關,而且Location updates選項勾選上。

第一步在info.plist文件中配置好了獲取用戶隱私權限後,第一次登入App,用戶會收到一個定位受權彈窗。根據用戶的選擇狀況,會走CLLocationManagerDelegate協議中的- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status方法。固然,也能夠經過CLAuthorizationStatus status = [CLLocationManager authorizationStatus];獲取當前用戶選擇的受權狀態,而後進行判斷作相應邏輯處理。通常處理以下:

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    NSLog(@"定位: %d",status);
    switch (status) {
        case kCLAuthorizationStatusNotDetermined:
            NSLog(@"用戶未作選擇");//能夠提示跳轉到設置
            break;
        case kCLAuthorizationStatusRestricted:
            NSLog(@"定位被限制");
            break;
        case kCLAuthorizationStatusDenied:
            NSLog(@"用戶拒絕獲取定位");
            break;
        case kCLAuthorizationStatusAuthorizedAlways:
            //用戶贊成永久訪問定位
            [self.locationManager requestAlwaysAuthorization];
            break;
        case kCLAuthorizationStatusAuthorizedWhenInUse:
            //用戶容許使用應用期間訪問定位
            [self.locationManager requestWhenInUseAuthorization];
            break;
        default:
            break;
    }
}
複製代碼

3、關於藍條問題的產生機理和處理辦法

這種藍條問題的產生和解決。

CLLocationManager管理類的配置

_locationManager = [[CLLocationManager alloc] init];
    _locationManager.delegate = self;
    _locationManager.distanceFilter = 100;
    _locationManager.desiredAccuracy = kCLLocationAccuracyBest;

    if ([[UIDevice currentDevice] systemVersion].floatValue >= 8) {
        /*
         有這麼一種說法
         若是兩個請求受權的方法都執行了,會出現如下狀況
         1.requestWhenInUseAuthorization寫在前面,第一次打開程序時請求受權,若是勾選了後臺模式,進入後臺會出現藍條提示正在定位。當程序退出,第二次打開程序時requestAlwaysAuthorization 會再次請求受權。以後進入後臺就不會出現藍色狀態欄。
         2.requestAlwaysAuthorization寫在前面, requestWhenInUseAuthorization寫在後面,只會在第一次打開程序時請求受權,由於requestAlwaysAuthorization獲得的受權大於requestWhenInUseAuthorization獲得的受權
         */
        [_locationManager requestAlwaysAuthorization];
        [_locationManager requestWhenInUseAuthorization];
    }
    if ([[UIDevice currentDevice] systemVersion].floatValue >= 9) {
        /*
         allowsBackgroundLocationUpdates:是否容許後臺定位,默認爲NO,只在iOS9.0以後起做用。
         設爲YES時,必須保證Background Modes 中的Location updates處於選中狀態,不然會拋出異常。
         在用戶選擇僅在使用應用期間獲取位置權限的狀況下,當應用進入後臺,手機桌面頂部是否出現藍條,這句代碼起着關鍵性做用。
         首先,這句代碼僅在requestWhenInUseAuthorization狀態下才起做用,不然不起做用。當設爲YES,就是容許在requestWhenInUseAuthorization此狀態下,即便App進入後臺,可是沒殺死,那麼就依然能夠後臺定位。而且頂部給個藍條閃爍,目的是在於實時提醒用戶:你這個App一直在獲取你的位置信息喲,若是你感到不須要繼續獲取了,就殺死該App吧!因此一直藍條閃爍。
         當設置爲NO,就是在requestWhenInUseAuthorization狀態下,App進入後臺,當即中止後臺定位。
         */
        _locationManager.allowsBackgroundLocationUpdates = YES;
        /*
         requestLocation和startUpdatingLocation這兩個方法很是相似,都會當即返回結果,將獲取的定位信息傳遞給委託對象的locationManager:didUpdateLocations:消息。
         不一樣點:
         startUpdatingLocation:能夠持續獲取定位。當設備移動的距離超過設定的distanceFilter屬性值時,接收器會再次生成一條更新消息。
         requestLocation:只產生一次定位信息,在此以後定位服務就中止了。而且:當使用這個方法時,委託對象必需要實現locationManager:didUpdateLocations:和locationManager:didFailWithError:方法。
         */
        [_locationManager requestLocation];
    } else {
        [_locationManager startUpdatingLocation];
        
    }
複製代碼

其實在上段代碼註釋中已經寫得較清楚了。

  • 藍條問題的產生前提:只在requestWhenInUseAuthorization這個狀態下才會出現。

  • 藍條出現的目的:由於用戶選擇的是僅在應用使用期間獲取位置,因此當app進入後臺後,系統將以藍條閃爍的形式不斷提醒用戶:主人,某某App一直在後臺獲取你的位置權限喲,若是你不須要用到了,你就直接將該App殺死吧,否則挺耗電的,若是有須要就當我沒說哈。

  • 藍條出現與否的背後代碼操控者:_locationManager.allowsBackgroundLocationUpdates = YES;若是不想出現藍條,直接設置爲NO,或者註釋,由於默認爲NO。

  • 另外,藍條出現與否的另外一種說法:跟下面兩句代碼的執行順序有關

[_locationManager requestAlwaysAuthorization];
        [_locationManager requestWhenInUseAuthorization];
複製代碼

詳見代碼註釋。

4、一張很經典的表格

此表早已一應俱全,望各位施主早日參透

告辭!

相關文章
相關標籤/搜索