首先對於定位功能實現的問題,詳見這幅帖子,超級全面詳細:【iOS】7.4 定位服務->2.1.2 定位 - 官方框架CoreLocation: CLLocationManager(位置管理器)bash
iOS定位權限自從iOS8以後就改動不少,出於對用戶隱私方面來講,若是要調用GPS模塊,就必須通過用戶肯定,體如今應用彈窗讓用戶選擇。須要在info.plist文件添加3個受權app
在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纔會用到
對於一些運動類、導航類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;
}
}
複製代碼
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];
複製代碼
詳見代碼註釋。
此表早已一應俱全,望各位施主早日參透
告辭!