iOS CLLocation對(duì)象詳解

一迷殿、簡(jiǎn)介

  • 作用:用來表示某個(gè)位置的地理信息蚜印,比如經(jīng)緯度豫喧、海拔等等
  • 常用屬性

// 經(jīng)緯度
@property(readonly,nonatomic)CLLocationCoordinate2Dcoordinate;
// 海拔
@property(readonly,nonatomic)CLLocationDistance altitude;
// 路線遭赂,航向(取值范圍是0.0°~359.9°摘符,0.0°代表真北方向,是根據(jù)gps定位,獲取的設(shè)備移動(dòng)方向)
@property(readonly,nonatomic)CLLocationDirection course;
// 移動(dòng)速度(單位是m/s)拷淘,當(dāng)前速度
@property(readonly,nonatomic)CLLocationSpeed speed;

 ```
  • 方法:可以計(jì)算2個(gè)位置之間的距離 -> 直線
     // 獲取兩個(gè)位置之間的直線物理距離
     - (CLLocationDistance)distanceFromLocation:(constCLLocation*)location
    

二、基本使用

  • 需求:打印當(dāng)前用戶的行走方向,偏離角度以及對(duì)應(yīng)的行走距離,

    • 例如:” 北偏東 30度 方向,移動(dòng)了 8 米”
  • 注意:


    1.png
  • 實(shí)現(xiàn)步驟:

    • 1> 獲取對(duì)應(yīng)的方向偏向(例如”正東””東偏南”)
    • 2> 獲取對(duì)應(yīng)的偏離角度(并判斷是否是正方向)
    • 3> 計(jì)算行走距離
    • 4> 打印信息
  • 思路分析:

    • 1.確定確定航向


      1.1版.png

      1.2.png
  • 2.確定偏移角度
3.png
4.png
5.png
6.png
  • 3.計(jì)算偏移距離


    5.png
  • 4.打又腹隆:


    6.png
  • 實(shí)現(xiàn)代碼:
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>

#define isIOS(version) ([[UIDevice currentDevice].systemVersion floatValue] >= version)

@interface ViewController ()<CLLocationManagerDelegate>
{
    CLLocation *_lastLocation;
}
/** 位置管理者 */
@property (nonatomic, strong) CLLocationManager *locationM;
@end

@implementation ViewController

#pragma mark -懶加載
-(CLLocationManager *)locationM
{
    if (!_locationM) {
              //1 創(chuàng)建位置管理者
        _locationM = [[CLLocationManager alloc] init];
        // 1.1 告訴外界位置的方案: 代理, block 通知
        _locationM.delegate = self;
        
        // 設(shè)置每隔多遠(yuǎn)定位一次(1次  111km/100m)
        // 最新的位置距離上一次位置之間的距離大于100m, 才會(huì)通過代理告訴外界
//        _locationM.distanceFilter = 100;
        
        
//         kCLLocationAccuracyBestForNavigation // 最適合導(dǎo)航
//         kCLLocationAccuracyBest; // 最好的
//         kCLLocationAccuracyNearestTenMeters; // 附近10米
//         kCLLocationAccuracyHundredMeters; // 100米
//         kCLLocationAccuracyKilometer; // 1000米
//         kCLLocationAccuracyThreeKilometers; // 3000米
        // 定位精確度
        // 定位精確度越高, 越耗電, 而且, 定位時(shí)間越長(zhǎng)
        _locationM.desiredAccuracy = kCLLocationAccuracyBest;
        
        //**-------ios8.0+定位適配---------- */
        if(isIOS(8.0))
        {
            // 請(qǐng)求前臺(tái)定位授權(quán)
            // 默認(rèn)情況下, 只能在前臺(tái)獲取用戶位置
            // 如果想要獲取后臺(tái)位置, 需要勾選后臺(tái)模式 location updates , 但是會(huì)出現(xiàn)藍(lán)條
                    [_locationM requestWhenInUseAuthorization];
            
            // 如果在iOS9.0+想要在前臺(tái)授權(quán)模式下, 在后臺(tái)獲取用戶位置, 我們需要額外的設(shè)置以下屬性為YES
            if (isIOS(9.0)) {
                _locationM.allowsBackgroundLocationUpdates = YES;
            }
            
            // 請(qǐng)求前后臺(tái)定位授權(quán)
            // 默認(rèn)在前后臺(tái)都可以獲取用戶位置信息, 無論是否勾選后臺(tái)模式locaiton updates, 而且不會(huì)出現(xiàn)藍(lán)條
            // 如果當(dāng)前的授權(quán)狀態(tài)!=用戶為選擇狀態(tài), 那么這個(gè)方法不會(huì)有效
//            [_locationM requestAlwaysAuthorization];
        }
      
        // 其它適配方案
//        if([_locationM respondsToSelector:@selector(requestAlwaysAuthorization)])
//        {
//            [_locationM requestAlwaysAuthorization];
//        }
    }
    return _locationM;
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
 
        // 2. 使用位置管理者, 開始獲取用戶位置
        // 開發(fā)經(jīng)驗(yàn): start 開始某個(gè)服務(wù)  stop 停止某個(gè)服務(wù)
    // 一旦調(diào)用了這個(gè)方法, 那么就會(huì)不斷的獲取用戶位置信息, 然后告訴外界
    // 默認(rèn)情況,只能在前臺(tái)獲取用戶位置信息, 如果我們想要在后臺(tái)獲取位置, 必須勾選后臺(tái)模式 location updates
    // 標(biāo)準(zhǔn)定位服務(wù)(基于gps/wifi/基站)
    [self.locationM startUpdatingLocation];

    
    // 監(jiān)聽重大位置的改變(基于基站進(jìn)行定位 , 要求, 設(shè)備必須有電話模塊)
//    [self.locationM startMonitoringSignificantLocationChanges];

    //         kCLLocationAccuracyBestForNavigation // 最適合導(dǎo)航
    //         kCLLocationAccuracyBest; // 最好的
    //         kCLLocationAccuracyNearestTenMeters; // 附近10米
    //         kCLLocationAccuracyHundredMeters; // 100米
    //         kCLLocationAccuracyKilometer; // 1000米
    //         kCLLocationAccuracyThreeKilometers; // 3000米
    // 請(qǐng)求一次位置信息
    // 注意 不能與startUpdatingLocation 一起使用
    if(isIOS(9.0))
    {

//        [self.locationM requestLocation];
    }
    
}


#pragma mark -CLLocationManagerDelegate
// 當(dāng)獲取到用戶位置信息時(shí)調(diào)用
// manager : 位置管理者
// locations: 位置數(shù)組 按時(shí)間進(jìn)行排序, 如果想要拿到最新的位置, 直接拿最后一個(gè)
// id+泛型 is kind of
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    // coordinate : 經(jīng)緯度坐標(biāo)
    // altitude : 海拔
    // horizontalAccuracy :水平海拔 如果是負(fù)數(shù), 代表當(dāng)前位置不可用
    // course : 航向(0---359.0)
    // - distanceFromLocation : 方法來計(jì)算兩個(gè)點(diǎn)之間的物理距離
    
    // 判斷當(dāng)前位置是否可用
    
    CLLocation *location = [locations lastObject];
    if(location.horizontalAccuracy < 0)
        return;
    
    // 場(chǎng)景演示:打印當(dāng)前用戶的行走方向,偏離角度以及對(duì)應(yīng)的行走距離,
    // 例如:” 北偏東  30度  方向,移動(dòng)了 8 米”
    // 1. 確定航向
    NSString *angleStr;
    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 substringToIndex:1];
    }
    
    
    // 確定行走了多少米
    double distance = 0;
    if (_lastLocation) {
        distance = [location distanceFromLocation:_lastLocation];
    }
    _lastLocation = location;
   // 例如:” 北偏東  30度  方向,移動(dòng)了 8 米”
    NSString *noticeStr;
    if (angle == 0) {
        noticeStr = [NSString stringWithFormat:@"正%@方向, 移動(dòng)了%f米", angleStr, distance];
    }else
    {
        noticeStr = [NSString stringWithFormat:@"%@%zd方向, 移動(dòng)了%f米", angleStr, angle, distance];
    }
    
    
    NSLog(@"%@", noticeStr);
    
    
//    NSLog(@"定位到了--%@", location);
    
    // 一般我們開發(fā)中, 獲取到用戶位置信息之后, 做一些業(yè)務(wù)邏輯操作
    // 針對(duì)于定位一次的情況, 可以在定位到之后 停止獲取用戶位置
//    [manager stopUpdatingLocation];
    
}

// 如果授權(quán)狀態(tài)發(fā)生變化時(shí),調(diào)用
// status : 當(dāng)前的授權(quán)狀態(tài)
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    switch (status) {
        case kCLAuthorizationStatusNotDetermined:
        {
            NSLog(@"用戶未決定");
             break;
        }
        case kCLAuthorizationStatusRestricted:
        {
            NSLog(@"受限制");
            break;
        }
        case kCLAuthorizationStatusDenied:
        {
            // 判斷當(dāng)前設(shè)備是否支持定位, 并且定位服務(wù)是否開啟()
            if([CLLocationManager locationServicesEnabled])
            {
                NSLog(@"定位開啟,被拒絕");
                // ios8,0- 需要截圖提醒引導(dǎo)用戶
                
                // iOS8.0+
//                NSURL *url = [NSURL URLWithString:]
//                if([[UIApplication sharedApplication] openURL:<#(NSURL *)#>])
                
            }else
            {
                NSLog(@"定位服務(wù)關(guān)閉");
            }
            break;
        }
        case kCLAuthorizationStatusAuthorizedAlways:
        {
             NSLog(@"前后臺(tái)定位授權(quán)");
            break;
        }
        case kCLAuthorizationStatusAuthorizedWhenInUse:
        {
            NSLog(@"前臺(tái)定位授權(quán)");
            break;
        }
            
        default:
            break;
    }
}

// 定位失敗調(diào)用
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"定位失敗");
}
@end

三启涯、應(yīng)用場(chǎng)景

    1. 導(dǎo)航
    1. 電商APP,獲取用戶所在城市
    1. 數(shù)據(jù)采集用戶信息(例如,統(tǒng)計(jì)app使用分布)
    1. 查找周邊(周邊好友, 周邊商家等等)

四贬堵、經(jīng)驗(yàn)

  • ** 為了給用戶省電,你可以這樣做 **
    • 1)不需要獲取用戶位置時(shí),一定要關(guān)閉定位服務(wù):
    • 2)如果能滿足項(xiàng)目需求,盡可能的使用”監(jiān)聽顯著位置變化”的定位服務(wù)(打車app)
    • 3)如果可以,盡可能使用低精度的desiredAccuracy
    • 4)如果是數(shù)據(jù)采集,(一般都是周期性的去輪詢用戶位置),在輪詢期間一定要關(guān)閉定位
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市结洼,隨后出現(xiàn)的幾起案子黎做,更是在濱河造成了極大的恐慌,老刑警劉巖松忍,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒸殿,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鸣峭,警方通過查閱死者的電腦和手機(jī)宏所,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來摊溶,“玉大人致开,你說我怎么就攤上這事挥吵。” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵晃虫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我航揉,道長(zhǎng)浦夷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任喊暖,我火速辦了婚禮听隐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘哄啄。我一直安慰自己雅任,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布咨跌。 她就那樣靜靜地躺著沪么,像睡著了一般。 火紅的嫁衣襯著肌膚如雪锌半。 梳的紋絲不亂的頭發(fā)上禽车,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音刊殉,去河邊找鬼殉摔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛记焊,可吹牛的內(nèi)容都是我干的逸月。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼遍膜,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼碗硬!你這毒婦竟也來了瓤湘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤恩尾,失蹤者是張志新(化名)和其女友劉穎弛说,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體翰意,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡木人,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了冀偶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片醒第。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蔫磨,靈堂內(nèi)的尸體忽然破棺而出淘讥,到底是詐尸還是另有隱情,我是刑警寧澤堤如,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布蒲列,位于F島的核電站,受9級(jí)特大地震影響搀罢,放射性物質(zhì)發(fā)生泄漏蝗岖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一榔至、第九天 我趴在偏房一處隱蔽的房頂上張望抵赢。 院中可真熱鬧,春花似錦唧取、人聲如沸铅鲤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)邢享。三九已至,卻和暖如春淡诗,著一層夾襖步出監(jiān)牢的瞬間骇塘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工韩容, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留款违,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓群凶,卻偏偏與公主長(zhǎng)得像插爹,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子座掘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容