- iOS的定位服務用到的框架是
#import <CoreLocation/CoreLocation.h> - 定位中用到的類是
CLLocationManager
一.iOS8.0之前的定位
- 向用戶描述授權的信息需要在info.plist中配以下key

- 后台情況下開啟定位服務需要進行如下圖配置

二.iOS8.0之后的定位(包含iOS8.0)
- iOS8.0之后前台定位授權和后台定位授權需要調用下面對應的方法
// 前台定位授權 官方文檔中說明info.plist中必須有NSLocationWhenInUseUsageDescription鍵
[_mgr requestWhenInUseAuthorization];
或者
// 前后台定位授權 官方文檔中說明info.plist中必須有NSLocationAlwaysUsageDescription鍵
[_mgr requestAlwaysAuthorization];
三.版本不同的適配問題(兩種方法)
- 方法一:
// 方法一:判斷iOS版本號
if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
// 前台定位授權 官方文檔中說明info.plist中必須有NSLocationWhenInUseUsageDescription鍵
[_mgr requestWhenInUseAuthorization];
// 前后台定位授權 官方文檔中說明info.plist中必須有NSLocationAlwaysUsageDescription鍵
[_mgr requestAlwaysAuthorization];
}
- 方法二:高大上的方法
// 方法二:判斷位置管理者能否響應iOS8之后的授權方法
if ([_mgr respondsToSelector:@selector(requestAlwaysAuthorization)]) {
// // 前台定位授權 官方文檔中說明info.plist中必須有NSLocationWhenInUseUsageDescription鍵
// [_mgr requestWhenInUseAuthorization];
// 前后台定位授權 官方文檔中說明info.plist中必須有NSLocationAlwaysUsageDescription鍵
[_mgr requestAlwaysAuthorization];
}
三.其余細節問題
- 位置管理者的精確度
/**
kCLLocationAccuracyBestForNavigation; --> 最適合導航
kCLLocationAccuracyBest; --> 最好的
kCLLocationAccuracyNearestTenMeters; --> 附近10米
kCLLocationAccuracyHundredMeters; --> 100米
kCLLocationAccuracyKilometer; --> 1000米
kCLLocationAccuracyThreeKilometers; --> 3000米
*/
// 設置定位所需的精度 枚舉值 精確度越高越耗電
self.mgr.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
- 位置管理者的過濾器,沒移動制定的距離定位一次
// 每100米更新一次定位
self.mgr.distanceFilter = 100;
四.代理方法中獲取定位到的位置信息,這里先不細講,下一次筆記詳細說明
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
NSLog(@"已經定位");
}
五.代理方法中監聽授權狀態的改變
// 代理方法中監聽授權的改變,被拒絕有兩種情況,一是真正被拒絕,二是服務關閉了
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch (status) {
case kCLAuthorizationStatusNotDetermined:
{
NSLog(@"用戶未決定");
break;
}
// 系統預留字段,暫時還沒用到
case kCLAuthorizationStatusRestricted:
{
NSLog(@"受限制");
break;
}
case kCLAuthorizationStatusDenied:
{
// 被拒絕有兩種情況 1.設備不支持定位服務 2.定位服務被關閉
if ([CLLocationManager locationServicesEnabled]) {
NSLog(@"真正被拒絕");
// 跳轉到設置界面
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
}
else {
NSLog(@"沒有開啟此功能");
}
break;
}
case kCLAuthorizationStatusAuthorizedAlways:
{
NSLog(@"前后台定位授權");
break;
}
case kCLAuthorizationStatusAuthorizedWhenInUse:
{
NSLog(@"前台定位授權");
break;
}
default:
break;
}
}
六.練習詳細代碼
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
@interface ViewController ()<CLLocationManagerDelegate>
/** 位置管理者 */
@property(nonatomic,strong) CLLocationManager *mgr;
@end
@implementation ViewController
#pragma mark - 懶加載
- (CLLocationManager *)mgr
{
if (_mgr == nil) {
// 實例化位置管理者
_mgr = [[CLLocationManager alloc] init];
// 指定代理,代理中獲取位置數據
_mgr.delegate = self;
// 兼容iOS8之后的方法
// 方法一:判斷iOS版本號
if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
// 前台定位授權 官方文檔中說明info.plist中必須有NSLocationWhenInUseUsageDescription鍵
[_mgr requestWhenInUseAuthorization];
// 前后台定位授權 官方文檔中說明info.plist中必須有NSLocationAlwaysUsageDescription鍵
[_mgr requestAlwaysAuthorization];
}
// 方法二:判斷位置管理者能否響應iOS8之后的授權方法
if ([_mgr respondsToSelector:@selector(requestAlwaysAuthorization)]) {
// // 前台定位授權 官方文檔中說明info.plist中必須有NSLocationWhenInUseUsageDescription鍵
// [_mgr requestWhenInUseAuthorization];
// 前后台定位授權 官方文檔中說明info.plist中必須有NSLocationAlwaysUsageDescription鍵
[_mgr requestAlwaysAuthorization];
}
}
return _mgr;
}
- (void)viewDidLoad {
[super viewDidLoad];
// 開啟位置更新
[self.mgr startUpdatingLocation];
/**
kCLLocationAccuracyBestForNavigation; --> 最適合導航
kCLLocationAccuracyBest; --> 最好的
kCLLocationAccuracyNearestTenMeters; --> 附近10米
kCLLocationAccuracyHundredMeters; --> 100米
kCLLocationAccuracyKilometer; --> 1000米
kCLLocationAccuracyThreeKilometers; --> 3000米
*/
// 設置定位所需的精度 枚舉值 精確度越高越耗電
self.mgr.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
// 每100米更新一次定位
self.mgr.distanceFilter = 100;
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
NSLog(@"已經定位");
}
// 代理方法中監聽授權的改變,被拒絕有兩種情況,一是真正被拒絕,二是服務關閉了
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch (status) {
case kCLAuthorizationStatusNotDetermined:
{
NSLog(@"用戶未決定");
break;
}
// 系統預留字段,暫時還沒用到
case kCLAuthorizationStatusRestricted:
{
NSLog(@"受限制");
break;
}
case kCLAuthorizationStatusDenied:
{
// 被拒絕有兩種情況 1.設備不支持定位服務 2.定位服務被關閉
if ([CLLocationManager locationServicesEnabled]) {
NSLog(@"真正被拒絕");
// 跳轉到設置界面
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
}
else {
NSLog(@"沒有開啟此功能");
}
break;
}
case kCLAuthorizationStatusAuthorizedAlways:
{
NSLog(@"前后台定位授權");
break;
}
case kCLAuthorizationStatusAuthorizedWhenInUse:
{
NSLog(@"前台定位授權");
break;
}
default:
break;
}
}
@end
