iOS原生類獲取定位授權(quán)是通過CoreLocation框架中的CLLocationManager類完成的,這其中可以解決兩大類場景的授權(quán)問題:
1、原生開發(fā)的授權(quán)
2、網(wǎng)頁混合開發(fā)的授權(quán)。使用webview加載網(wǎng)頁,授權(quán)歸入APP授權(quán);在瀏覽器中加載頁面,授權(quán)歸入瀏覽器授權(quán)。
一、概述獲取權(quán)限過程
1、調(diào)用authorizationStatus,獲取狀態(tài),只要不是允許狀態(tài),進行下個步驟
2、CLLocationManager創(chuàng)建實例,并設置代理
3、保持CLLocationManager實例的生命周期到任務結(jié)束
4、如果授權(quán)狀態(tài)不是允許,則獲取授權(quán)或者跳轉(zhuǎn)設置頁面繼續(xù)修改
5、根據(jù)需要開啟不同的定位服務
二、獲取授權(quán)狀態(tài)
//次方法返回值為CLAuthorizationStatus的枚舉類型,如下所示
[CLLocationManager authorizationStatus];
typedef NS_ENUM(int, CLAuthorizationStatus) {
//未做選擇:未選允許、拒絕(例如彈出提示框,用戶之間退出APP時會發(fā)生)
kCLAuthorizationStatusNotDetermined = 0,
//受限制:未授權(quán),主動現(xiàn)在定位服務,用戶無法改變該狀態(tài)(可能沒有否認個人授權(quán))
kCLAuthorizationStatusRestricted,
// 拒絕:用戶拒絕授權(quán),可在設置在修改
kCLAuthorizationStatusDenied,
//授權(quán)且在未使用APP時使用定位
kCLAuthorizationStatusAuthorizedAlways NS_ENUM_AVAILABLE(NA, 8_0),
// 授權(quán)且當APP使用中使用定位
kCLAuthorizationStatusAuthorizedWhenInUse NS_ENUM_AVAILABLE(NA, 8_0),
// 已廢棄:不做解釋,在官方demo中也不在關注該值
kCLAuthorizationStatusAuthorized NS_ENUM_DEPRECATED(10_6, NA, 2_0, 8_0, "Use kCLAuthorizationStatusAuthorizedAlways") __TVOS_PROHIBITED __WATCHOS_PROHIBITED = kCLAuthorizationStatusAuthorizedAlways
};
根據(jù)當前授權(quán)狀態(tài)做響應的交互處理:
#pragma mark - 檢查授權(quán)狀態(tài)
- (void)checkLocationServicesAuthorizationStatus {
[self reportLocationServicesAuthorizationStatus:[CLLocationManager authorizationStatus]];
}
- (void)reportLocationServicesAuthorizationStatus:(CLAuthorizationStatus)status
{
if(status == kCLAuthorizationStatusNotDetermined)
{
//未決定,繼續(xù)請求授權(quán)
[self requestLocationServicesAuthorization];
}
else if(status == kCLAuthorizationStatusRestricted)
{
//受限制,嘗試提示然后進入設置頁面進行處理(根據(jù)API說明一般不會返回該值)
[self alertViewWithMessage];
}
else if(status == kCLAuthorizationStatusDenied)
{
//拒絕使用,提示是否進入設置頁面進行修改
[self alertViewWithMessage];
}
else if(status == kCLAuthorizationStatusAuthorizedWhenInUse)
{
//授權(quán)使用,不做處理
}
else if(status == kCLAuthorizationStatusAuthorizedAlways)
{
//始終使用,不做處理
}
}
#pragma mark - Helper methods
- (void)alertViewWithMessage {
UIAlertView *alter = [[UIAlertView alloc] initWithTitle:@"定位服務未開啟" message:@"請在系統(tǒng)設置中開啟服務" delegate:self cancelButtonTitle:@"暫不" otherButtonTitles:@"去設置", nil];
[alter show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
}
else
{
//進入系統(tǒng)設置頁面,APP本身的權(quán)限管理頁面
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}
}
三、獲取授權(quán)
#pragma mark - 獲取授權(quán)
- (void)requestLocationServicesAuthorization
{
//CLLocationManager的實例對象一定要保持生命周期的存活
if (!self.locationManager) {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
}
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager startUpdatingLocation];
}
#pragma mark - CLLocationMangerDelegate methods
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
[self.locationManager stopUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
[self.locationManager stopUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
[self reportLocationServicesAuthorizationStatus:status];
}
關于以上代碼幾點說明
1、CLLocationManager的對象實例一定要保證生命周期存在知道任務結(jié)束,因為定位服務的任務執(zhí)行時異步,使用局部變量不能保證定位服務正常進行。
2、iOS8系統(tǒng)之后一定要在info.plist文件中添加NSLocationWhenInUseUsageDescription或者NSLocationAlwaysUsageDescription,根據(jù)需要選擇其一或者其二(決定了授權(quán)設置頁面中選項數(shù)目),內(nèi)容選填。
3、requestWhenInUseAuthorization或者requestAlwaysAuthorization方法,要在使用定位服務(比如startUpdatingLocation)之前調(diào)用。
4、APP進入后臺運行的時候,開啟定位服務會失敗。
5、當進行授權(quán)選擇后,會調(diào)用didChangeAuthorizationStatus方法,此時重新走一次檢測授權(quán)狀態(tài)過程。
四、調(diào)用方法開始整個獲取權(quán)限流程
- (void)viewDidLoad {
[super viewDidLoad];
[self checkLocationServicesAuthorizationStatus];
}
只需要調(diào)用次方法即可。
五、最后的話
定位服務還有其他內(nèi)容,學習了其他內(nèi)容會繼續(xù)更新,詳情請參考官方文檔,關于其他系統(tǒng)服務權(quán)限的獲取,可以參考另一篇文章和官方Demo。