快速入門:CoreLocation框架進行定位和iOS不一樣版本間定位的差別

使用CoreLocation框架進行定位

  • 廢話很少說,直接上乾貨

1. iOS8以前的定位

  • 直接上代碼,代碼裏面有詳細的步驟
#import "ViewController.h"
// 0. 導入頭文件
#import <CoreLocation/CoreLocation.h>

@interface ViewController () <CLLocationManagerDelegate>
/** 位置管理者 */
@property (nonatomic, strong) CLLocationManager *manager;
@end

@implementation ViewController
- (CLLocationManager *)manager
{
    if (!_manager) {
        // 1. 建立CLLocationManager
        _manager = [[CLLocationManager alloc] init];
        // 2. 設置代理
        _manager.delegate = self;

        // 每隔多少米定位一次
        _manager.distanceFilter = 100;

        /**
         kCLLocationAccuracyBestForNavigation // 最適合導航
         kCLLocationAccuracyBest; // 最好的精確度,僅次於kCLLocationAccuracyBestForNavigation
         kCLLocationAccuracyNearestTenMeters; // 附近10m
         kCLLocationAccuracyHundredMeters; // 100m
         kCLLocationAccuracyKilometer; // 1公里
         kCLLocationAccuracyThreeKilometers; // 3公里
         */
        // 設置定位精確度
        // 並非精確度越高就越好,精確度越高,就越耗性能,越費電,要根據需求來設置精確度
        _manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    }
    return _manager;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 3.開始更新地址
    // 此處重點:必定要在info.plist文件中加上key:Privacy - Location Usage Description,value能夠隨便寫
    [self.manager startUpdatingLocation];


}

#pragma mark - 實現CLLocationManagerDelegate代理方法
// 4.實現代理方法
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    CLLocation *location = [locations lastObject];
    NSLog(@"%@ -- %f", location.description, location.speed);
}
@end
  • 注意點:第三步出,必定要在info.plist文件中加上key:Privacy - Location Usage Description,如圖所示:

2.iOS8的定位

  • iOS8相對於以前的版本,蘋果進一步增強了對用戶隱私的保護。
    當APP想訪問用戶的隱私信息時,系統再也不自動彈出一個對話框讓用戶受權
  • 解決方案:
    • (1)調用iOS 8.0的API,主動請求用戶受權
      • -(void)requestAlwaysAuthorization // 請求容許在先後臺都能獲取用戶位置的受權
      • -(void)requestWhenInUseAuthorization // 請求容許在前臺獲取用戶位置的受權
    • (2)務必在info.plist文件中配置對應的鍵值, 不然以上請求受權的方法不生效
      NSLocationAlwaysUsageDescription : 容許在先後臺獲取GPS的描述
      NSLocationWhenInUseDescription : 容許在前臺獲取GPS的描述
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>

@interface ViewController () <CLLocationManagerDelegate>
/** 位置管理者 */
@property (nonatomic, strong) CLLocationManager *manager;
@end

@implementation ViewController
- (CLLocationManager *)manager
{
    if (_manager == nil) {
        _manager = [[CLLocationManager alloc] init];
        _manager.delegate = self;

        // 採起前臺定位
        // 1. 須要在info.plist文件中添加key:NSLocationWhenInUseUsageDescription
        // 2. 若是須要在後臺繼續定位,須要勾選後臺模式,當程序進入後臺後,會在最上方出現一個藍條
//        [_manager requestWhenInUseAuthorization];

        // 採用先後臺定位
        // 1. 須要在info.plist文件中添加NSLocationAlwaysUsageDescription這個key
        // 2. 這種模式的後臺定位,不須要勾選後臺模式,也不會出現藍條
        [_manager requestAlwaysAuthorization];


        // requestWhenInUseAuthorization和requestAlwaysAuthorization請求同時存在:
        // 1. requestWhenInUseAuthorization請求在前,會先彈出前臺受權描述,第二次啓動程序的時候,還會彈出先後臺受權描述
        // 2. requestAlwaysAuthorization在前,只會彈出先後臺受權描述,不會彈出前臺受權描述.
    }
    return _manager;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.manager startUpdatingLocation];

}

#pragma mark - <CLLocationManagerDelegate>
/**
 *  更新定位
 *
 *  @param manager   位置管理器
 *  @param locations 定位的位置數組
 */
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    NSLog(@"定位了");
}

3. iOS9 的定位

  • 在iOS9中,若是使用requestWhenInUseAuthorization,跟iOS8同樣,不只須要設置info.plist,若是想要在後臺定位,也須要勾選後臺模式,還須要設置allowsBackgroundLocationUpdates=Yes.一樣也會出現藍條
_manager.allowsBackgroundLocationUpdates = YES;
  • iOS 9.0 能夠單次請求用戶位置:-(void)requestLocation
    • 做用是按照定位的精確度從低到高進行排序,逐個進行定位.若是獲取到的位置不是精確度最高的那個,也會在定位超時後,經過代理告訴外界(必須實現代理的-locationManager:didFailWithError:方法, 不能與startUpdatingLocation方法同時使用)
- (void)requestLocation
-(void)locationManager:(nonnull CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations  // 成功調用
-(void)locationManager:(nonnull CLLocationManager *)manager didFailWithError:(nonnull NSError *)error // 失敗調用

4. CLLocation

  • 以一個小的需求來學習CLLocation
  • 一個小需求:打印當前用戶的行走方向,偏離角度以及對應的行走距離, 例如:」北偏東30度方向,移動了8米」
/**
 *  代理方法: 更新定位
 *
 *  @param manager   位置管理器
 *  @param locations 定位的位置數組
 */
- (void)locationManager:(nonnull CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations
{
    // CLLocation經常使用屬性
    // coordinate   (當前位置所在的經緯度)
    // altitude (海拔)
    // speed    (當前速度)
    // course (航向)

    // -distanceFromLocation (獲取兩個位置之間的直線物理距離)

    CLLocation *location = [locations lastObject];

    // 1. 獲取偏向角度
    NSString *angleStr = nil;

    switch ((int)location.course / 90) {
        case 0:
            angleStr = @"北偏東";
            break;
        case 1:
            angleStr = @"東偏南";
            break;
        case 2:
            angleStr = @"南偏西";
            break;
        case 3:
            angleStr = @"西偏北";
            break;
        default:
            angleStr = @"未知位置";
            break;
    }

    // 2. 偏移角度
    NSInteger angle = (int)location.course % 90;
    if (angle == 0) { // 表示正方向
        angleStr = [angleStr substringWithRange:NSMakeRange(0, 1)];
    }

    // 3. 移動了多少米
    double distance = 0;
    if (_oldLocation) {
        distance = [location distanceFromLocation:_oldLocation];
    }
    _oldLocation = location;

    // 4. 打印
    NSString *locationStr = [NSString stringWithFormat:@"%@%zd度方向,移動了%.2fm", angleStr, angle, distance];
    NSLog(@"%@", locationStr);
}

5.定位的其餘補充

  • 受權狀態
kCLAuthorizationStatusNotDetermined = 0, // 用戶未決定

     kCLAuthorizationStatusRestricted, // 受限制

     kCLAuthorizationStatusDenied, // 拒絕

     kCLAuthorizationStatusAuthorizedAlways NS_ENUM_AVAILABLE(NA, 8_0), // 永久受權

     kCLAuthorizationStatusAuthorizedWhenInUse NS_ENUM_AVAILABLE(NA, 8_0), // APP使用的時候受權
相關文章
相關標籤/搜索