IOS CoreLocation中CLLocationManager類的基本使用

liushaozhuanyong發表於2017-08-05
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>

@interface ViewController ()<CLLocationManagerDelegate>

/**
 iOS8以後, 要定位, 必須使用位置管理器(授權), 使用 Strong 屬性, 保證不被釋放
 */
@property (nonatomic, strong) CLLocationManager *locationManager;

@end

@implementation ViewController

/**
 如果定位方法不走
 1. 沒有配置 plist 鍵值
 2. 模擬器 bug
 3. 沒有使用 strong 的屬性
 */

- (void)viewDidLoad {
    [super viewDidLoad];
    //想要使用定位, 必須使用CLLocationManager

    //1. 建立位置管理器
    self.locationManager = [CLLocationManager new];

    //2. 請求使用者授權(iOS8以後才有) 同時配置 plist 列表

    //使用者使用時授權 大部分的應用應該使用此種授權方式
    // 判斷可以使用巨集定義(獲取系統版本號)  / respondsToSelector
    if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
        [self.locationManager requestWhenInUseAuthorization];
    }

    /*
    2. 請求使用者授權 --> 從iOS8開始, 必須在程式中請求使用者授權, 除了寫程式碼, 還要配置plist列表的鍵值
    如果要適配iOS7, 一定要加if判斷, 因為低版本的SDK沒有授權方法
    if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) { }

     1. 如果要授權, 從iOS8開始, 必須在程式中請求使用者授權, 除了寫程式碼, 還要配置plist列表的鍵值
     2. 授權方式 -->requestWhenInUseAuthorization 當使用者使用的使用授權
                -->requestAlwaysAuthorization 永久授權方法
     3. 一定要記得授權方法和plist列表匹配 (when / always) 
        NSLocationWhenInUseUsageDescription
        NSLocationAlwaysUsageDescription

     4. 如果2個方法都寫, 會出現2此授權的情況 (第一次會走第一個方法, 第二次會走第二個方法 --> 一般使用1個方法即可

     5. 大部分的程式之使用 "使用期間" 這個授權即可. 如果說列表出出現了3個, 說明兩個授權方法寫了
     6. plist的Value 可以不寫, 寫上是為了提示使用者, 當前程式會在哪些地方使用定位. 建議寫上, 提高使用者開啟的機率
     )
     */

    if ([self.mgr respondsToSelector:@selector(requestWhenInUseAuthorization)]){

        //當使用者使用的使用授權 --> 能看見APP介面的時候就是使用期間
        [self.mgr requestWhenInUseAuthorization];

        //永久授權方法 --> 鎖屏 / 退出後臺
//        [self.mgr requestAlwaysAuthorization];
    }



    /**
     iOS9新特性 --> 臨時獲取後臺定位許可權
     */

    //allowsBackgroundLocationUpdates 如果實現了此方法, 還需要配置plist列表

    //一定注意適配版本, 要加iOS9判斷
    if ([UIDevice currentDevice].systemVersion.floatValue >= 9.0) {
        self.mgr.allowsBackgroundLocationUpdates = YES;
    }




    //3. 設定代理 --> 獲取使用者位置
    self.mgr.delegate = self;

    //4. 呼叫開始定位方法
    [self.mgr startUpdatingLocation];

    // 比較兩個位置之前的距離
    // 北京和西安的距離
    // 建立一個位置物件, 最少只需要兩個值, 經緯度
    CLLocation *location1 = [[CLLocation alloc] initWithLatitude:40 longitude:116];
    CLLocation *location2 = [[CLLocation alloc] initWithLatitude:34.27 longitude:108.93];

    // 比較的是直線距離
    CLLocationDistance distance = [location1 distanceFromLocation:location2];
    NSLog(@"distance: %f",distance / 1000);
}

#pragma mark 代理方法
/** 當完成位置更新的時候呼叫 --> 次方法會頻繁呼叫*/
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{

    CLLocation *location = locations.lastObject;

    //NSLog(@"locations: %@",location);

    //5. 停止定位
    //[self.mgr stopUpdatingLocation];
    **/

    //3. 設定代理, 來獲取資料
    self.locationManager.delegate = self;

    //4. 開始定位
    [self.locationManager startUpdatingLocation];


    /**
     為了省電, 所有要對持續定位 app 進行優化
     */

    //5. 距離篩選器 (當使用者發生一定位置的改變時, 再去呼叫代理方法, 以此實現省電)
    // 值: 多少米  譬如:設定10, 就代表使用者位置發生10米以上的偏移時, 才去定位
    self.locationManager.distanceFilter = 10;

    //6. 設定精確度 (減少為衛星之間的計算, 以此實現省電)
    // 定位的方式: GPS 北斗 基站定位 WiFi 定位
    // iPhone開啟定位: GPS 跟24顆衛星進行通訊
    //desired: 期望
    //Accurac: 精準度

    //iOS9以前預設kCLLocationAccuracyBest
//    self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
    NSLog(@"self.%zd",self.locationManager.desiredAccuracy);

}

/**
 當使用者更新位置的時候呼叫此方法  頻繁呼叫, 非常耗電
 */
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    //CLLocation 位置物件 --> 經緯度
    //CLLocationCoordinate2D coordinate 經緯度
    //CLLocationDegrees latitude   緯度
    //CLLocationDegrees longitude  經度

    CLLocation *location = locations.firstObject;
    NSLog(@"latitude: %f,longitude: %f",location.coordinate.latitude, location.coordinate.longitude);

}


@end

CLLocation

  • 包括幾個重要的屬性:
    • coordinate中包含經度、維度兩個屬性
  • 重要的方法distanceFromLocation 計算該點與本點之間的直線距離
  • //CLLocation : 位置物件, 最核心的就是經緯度
    //CLLocationCoordinate2D coordinate : 2D位置座標 –> 經緯度

    //CLLocationDegrees latitude; –> 緯度
    //CLLocationDegrees longitude; –> 經度

相關文章