重點(diǎn) (十七) : CoreLocation

簡介

在移動互聯(lián)網(wǎng)時代,移動app能解決用戶的很多生活瑣事顶瞒,比如

周邊:找餐館、找KTV元旬、找電影院等等

導(dǎo)航:根據(jù)用戶設(shè)定的起點(diǎn)和終點(diǎn)榴徐,進(jìn)行路線規(guī)劃,并指引用戶如何到達(dá)

在上述應(yīng)用中匀归,都用到了定位和地圖功能坑资,在iOS開發(fā)中,要想加入這2大功能穆端,必須基于2個框架進(jìn)行開發(fā)

CoreLocation :用于地理定位袱贮,地理編碼,區(qū)域監(jiān)聽等(著重功能實(shí)現(xiàn))

MapKit :用于地圖展示体啰,例如大頭針攒巍,路線、覆蓋層展示等(著重界面展示)

2個熱門專業(yè)術(shù)語

LBS :Location Based Service

SoLoMo :Social Local
Mobile(索羅門)(機(jī)會 社交 位置)

1.png

CLLocationManager

CLLocationManager的常用操作

開始更新用戶位置

-(void)startUpdatingLocation;

停止更新用戶位置

-(void) stopUpdatingLocation;

當(dāng)調(diào)用了startUpdatingLocation方法后荒勇,就開始不斷地請求柒莉、刷新用戶的位置,一旦請求到用戶位置就會調(diào)用代理的下面方法

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;

locations參數(shù)里面裝著CLLocation對象

CLLocationManager補(bǔ)充

為了嚴(yán)謹(jǐn)起見枕屉,最好在使用定位功能之前判斷當(dāng)前應(yīng)用的定位功能是否可用

CLLocationManager有個類方法可以判斷當(dāng)前應(yīng)用的定位功能是否可用

  • (BOOL)locationServicesEnabled;

@property(assign, nonatomic) CLLocationDistance
distanceFilter;

每隔多少米定位一次

@property(assign, nonatomic) CLLocationAccuracy
desiredAccuracy;

定位精確度(越精確就越耗電)

CLLocation

CLLocation用來表示某個位置的地理信息常柄,比如經(jīng)緯度鲤氢、海拔等等

@property(readonly, nonatomic) CLLocationCoordinate2D
coordinate;

經(jīng)緯度

@property(readonly, nonatomic) CLLocationDistance
altitude;

海拔

@property(readonly, nonatomic) CLLocationDirection
course;

路線搀擂,航向(取值范圍是0.0°~ 359.9°,0.0°代表真北方向)

@property(readonly, nonatomic) CLLocationSpeed speed;

移動速度(單位是m/s)

用- (CLLocationDistance)distanceFromLocation:(const CLLocation*)location方法可以計算2個位置之間的距離

2.png

3.png

iOS 8.0+ 的定位適配

從iOS 8.0開始卷玉,蘋果進(jìn)一步加強(qiáng)了對用戶隱私的保護(hù)哨颂。

當(dāng)APP想訪問用戶的隱私信息時,系統(tǒng)不再自動彈出一個對話框讓用戶授權(quán)

解決方案:

(1)調(diào)用iOS 8.0的API相种,主動請求用戶授權(quán)

  • (void)requestAlwaysAuthorization 請求允許在前后臺都能獲取用戶位置的授權(quán)

  • (void)requestWhenInUseAuthorization 請求允許在前臺獲取用戶位置的授權(quán)

(2)務(wù)必在info.plist文件中配置對應(yīng)的鍵值威恼, 否則以上請求授權(quán)的方法不生效

NSLocationAlwaysUsageDescription : 允許在前后臺獲取GPS的描述

NSLocationWhenInUseDescription : 允許在前臺獲取GPS的描述

iOS 9.0 定位補(bǔ)充

iOS 9.0 如果當(dāng)前處于前臺授權(quán)狀態(tài),默認(rèn)是不可以后臺獲取用戶位置。但可以設(shè)置以下屬性為YES箫措,就可以繼續(xù)獲取后臺位置腹备,但是會出現(xiàn)藍(lán)條

@property(assign, nonatomic) BOOL
allowsBackgroundLocationUpdates

使用注意:必須設(shè)置打開對應(yīng)的后臺模式:location updates

iOS 9.0 可以單次請求用戶位置

  • (void)requestLocation

-(void)locationManager:(nonnull CLLocationManager
*)manager didUpdateLocations:(nonnull NSArray<CLLocation *>
*)locations 成功調(diào)用

-(void)locationManager:(nonnull CLLocationManager *)manager
didFailWithError:(nonnull NSError *)error
失敗調(diào)用

CLLocationCoordinate2D

CLLocationCoordinate2D是一個用來表示經(jīng)緯度的結(jié)構(gòu)體,定義如下

typedef struct {

    CLLocationDegreeslatitude;  緯度

    CLLocationDegreeslongitude;  經(jīng)度

}
CLLocationCoordinate2D;

一般用CLLocationCoordinate2DMake函數(shù)來創(chuàng)建CLLocationCoordinate2D

4.png

5.png

6.png

CLGeocoder

使用CLGeocoder可以完成“地理編碼”和“反地理編碼”

地理編碼:根據(jù)給定的地名斤蔓,獲得具體的位置信息(比如經(jīng)緯度植酥、地址的全稱等)

反地理編碼:根據(jù)給定的經(jīng)緯度,獲得具體的位置信息

地理編碼方法

-(void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;

反地理編碼方法

  • (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;

CLGeocodeCompletionHandler

當(dāng)?shù)乩韁反地理編碼完成時弦牡,就會調(diào)用CLGeocodeCompletionHandler

typedef void (^CLGeocodeCompletionHandler)(NSArray *placemarks, NSError *error);

這個block傳遞2個參數(shù)

error :當(dāng)編碼出錯時(比如編碼不出具體的信息)有值

place marks :里面裝著CLPlacemark對象

CLPlacemark

CLPlacemark的字面意思是地標(biāo)友驮,封裝詳細(xì)的地址位置信息

@property (nonatomic, readonly) CLLocation *location;

地理位置

@property (nonatomic, readonly) CLRegion *region; 區(qū)域

@property (nonatomic, readonly) NSDictionary *addressDictionary;

詳細(xì)的地址信息

@property (nonatomic, readonly) NSString *name;

地址名稱

@property (nonatomic, readonly) NSString *locality; 城市

*************************筆記**************************


一. iOS8.0之前的定位(?????)

iOS8特性:

1.iOS8.0+前后臺的定位授權(quán)描述

NSLocationAlwaysUsageDescription

2.iOS8.0前-定位描述

Privacy

  • Location Usage Description

3.iOS8.0+前臺定位授權(quán)描述

NSLocationWhenInUseUsageDescription

4.在iOS8.0之后是前臺定位,那么當(dāng)APP退到后臺時,屏幕頂部會出現(xiàn)藍(lán)條

5.不需要勾選后臺模式,也可以進(jìn)行后臺定位

注意:此時授權(quán)狀態(tài)如果是前后臺定位,那么當(dāng)APP退到后臺時,屏幕頂部不會出現(xiàn)藍(lán)條

iOS9:

注意:

1.如果在iOS9.0,如果在前臺定位授權(quán)狀態(tài)下,(想要在后臺也獲取用戶位置),不但要勾選后臺模式Location
Updates,還要做以下設(shè)置:_locationM.allowsBackgroundLocationUpdates= YES;

2.此時授權(quán)狀態(tài)如果是前后臺定位,那么當(dāng)APP退到后臺時,屏幕頂部不會出現(xiàn)藍(lán)條

如果授權(quán)狀態(tài)為前臺定位,那么當(dāng)APP退到后臺時,屏幕同樣會出現(xiàn)藍(lán)條

  1. 前臺定位

CoreLocation框架

一. iOS8.0之前的定位(?????)

  1. 前臺定位
  1. 導(dǎo)入CoreLocation框架以及對應(yīng)的主頭文件

import <CoreLocation/CoreLocation.h>

  1. 創(chuàng)建CLLocationManager對象并設(shè)置代理

self.locationM = [[CLLocationManager alloc] init];

self.locationM.delegate = self;

  1. 調(diào)用方法,開始更新用戶位置信息

[self.locationM startUpdatingLocation];

  1. 在對應(yīng)的代理方法中獲取位置信息

-(void)locationManager:(nonnull
CLLocationManager *)manager didUpdateLocations:(nonnull
NSArray<CLLocation > *)locations

{

NSLog(@"每當(dāng)請求到位置信息時, 都會調(diào)用此方法");

}

  1. 后臺定位

  2. 在前臺定位基礎(chǔ)上,
    勾選后臺模式Location updates

7.png
  1. 額外設(shè)置

  2. 每隔多少米定位一次

代碼: self.locationM.distanceFilter = 100;

功能: 只有當(dāng)最新的位置與上一次獲取的位置之間的距離, 大于這個值時, 才會通過代理告訴外界

  1. 設(shè)置定位精確度

代 碼: self.locationM.desiredAccuracy = kCLLocationAccuracyBest;

功 能: 通過設(shè)置此屬性, 獲取不同精確度的位置信息

注意事項(xiàng): 精確度越高,越耗電驾锰,定位所需時間越長

枚舉注解:

|
枚舉值 | 含義
|

------------

|
kCLLocationAccuracyBestForNavigation | 最適合導(dǎo)航 |

|
kCLLocationAccuracyBest | 精度最好的 |

|
kCLLocationAccuracyNearestTenMeters | 附近10米
|

|
kCLLocationAccuracyHundredMeters | 附近100米|

|
kCLLocationAccuracyKilometer | 附近1000米 |

|
kCLLocationAccuracyThreeKilometers | 附近3000米 |

  1. 知識補(bǔ)充
  1. 定位常識
  1. 標(biāo)準(zhǔn)定位服務(wù)(基于gps/基站/wifi定位, 具體使用哪種,蘋果有自己規(guī)則)

程序關(guān)閉,就沒法獲取位置

  1. 顯著的位置變化定位服務(wù)(使用基站進(jìn)行定位,所以必須要求設(shè)備有電話模塊)

當(dāng)app被完全關(guān)閉時,也可以接收到位置通知,并讓app進(jìn)入到后臺處理

定位精度相比于上面,精度不大,所以耗電小,而且定位更新頻率依據(jù)基站密度而定

  1. 應(yīng)用場景
  1. 如果要求定位及時,精度較高,并且運(yùn)行時間較短,可使用標(biāo)準(zhǔn)定位;

  2. 如果長時間監(jiān)控用戶位置,用戶移動速度比較快(例如打車軟件),可使用后者

  1. 測試環(huán)境:

XCode7.0之前版本,例如XCode6.4版本

  1. 模擬器選擇iOS8.0之前的版本
  • 原因 :
    XCode7.0(包含7.0)之后不支持iOS8.0之前的模擬器
  1. 常見問題總結(jié)

  2. 定位不到, 對應(yīng)的代理方法不執(zhí)行

首先,檢查運(yùn)行的模擬器是否是iOS8.0之前的系統(tǒng)版本

其次,檢查模擬器是否設(shè)置位置數(shù)據(jù)

第三,確保代碼無問題(一般都是代理沒有設(shè)置,或者位置管理器對象是局部變量,亦或是位置管理器對象沒有被強(qiáng)引用)

第四,絕逼是模擬器BUG, 請重置模擬器(是重置,不是重啟)

二. iOS8.0之后定位(?????)

  1. 前臺定位
  1. 導(dǎo)入CoreLocation框架以及對應(yīng)的主頭文件

import <CoreLocation/CoreLocation.h>

  1. 創(chuàng)建CLLocationManager對象并設(shè)置代理

self.locationM = [[CLLocationManager alloc] init];

self.locationM.delegate = self;

  1. 請求前臺定位授權(quán),
    并在Info.Plist文件中配置Key(Nslocationwheninuseusagedescription)

在前后臺都可以獲取用戶位置信息, 無論是否勾選后臺模式

[self.locationM requestWhenInUseAuthorization];

  1. 調(diào)用方法,開始更新用戶位置信息

[self.locationM startUpdatingLocation];

  1. 在對應(yīng)的代理方法中獲取位置信息

-(void)locationManager:(nonnull
CLLocationManager *)manager didUpdateLocations:(nonnull
NSArray<CLLocation > *)locations

{

NSLog(@"每當(dāng)請求到位置信息時, 都會調(diào)用此方法");

}

  1. 后臺定位
    方案一:

  2. 在前臺定位基礎(chǔ)上,
    勾選后臺模式Location updates

8.png

注意:此時授權(quán)狀態(tài)如果是前臺定位, 那么當(dāng)APP退到后臺時, 屏幕頂部會出現(xiàn)藍(lán)條

方案二:

  1. 請求前后臺定位授權(quán),并在info.plist文件中配置KEY NSLocationWhenInUseUsageDescription iOS8.0+前臺定位授權(quán)描述

[self.locationM requestAlwaysAuthorization];

注意:不需要勾選后臺模式, 也可以進(jìn)行后臺定位

注意:此時授權(quán)狀態(tài)如果是前后臺定位, 那么即使APP退到后臺時, 屏幕頂部會也不會出現(xiàn)藍(lán)條

  1. 監(jiān)聽用戶授權(quán)狀態(tài)

  2. 實(shí)現(xiàn)以下代理方法即可

表示當(dāng)前應(yīng)用程序的授權(quán)狀態(tài)卸留。

(CLAuthorizationStatus)status

當(dāng)用戶授權(quán)狀態(tài)發(fā)生變化時調(diào)用

-(void)locationManager:(nonnull
CLLocationManager *)manager
didChangeAuthorizationStatus:(CLAuthorizationStatus)status

{

switch (status) {

      用戶還未決定

case
kCLAuthorizationStatusNotDetermined:

{

      NSLog(@"用戶還未決定");

 
  break;

}

        訪問受限(蘋果預(yù)留選項(xiàng),暫時沒用)

case
kCLAuthorizationStatusRestricted:

{

      NSLog(@"訪問受限");

 
  break;

}

        定位關(guān)閉時和對此APP授權(quán)為never時調(diào)用

case kCLAuthorizationStatusDenied:

{

        定位是否可用(是否支持定位或者定位是否開啟)

 
  if([CLLocationManager

locationServicesEnabled])

  {


          NSLog(@"定位開啟,但被拒");

            在此處, 應(yīng)該提醒用戶給此應(yīng)用授權(quán),

并跳轉(zhuǎn)到"設(shè)置"界面讓用戶進(jìn)行授權(quán)

            在iOS8.0之后跳轉(zhuǎn)到"設(shè)置"界面代碼

 
      NSURL *settingURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];

      if([[UIApplication

sharedApplication] canOpenURL:settingURL])

      {

 
          [[UIApplication sharedApplication] openURL:settingURL];

 
      }

 
  }else

 
  {


          NSLog(@"定位關(guān)閉椭豫,不可用");

 
  }

 
  break;

}

      獲取前后臺定位授權(quán)

case
kCLAuthorizationStatusAuthorizedAlways:

        case kCLAuthorizationStatusAuthorized: 失效耻瑟,不建議使用

{

      NSLog(@"獲取前后臺定位授權(quán)");

 
  break;

}

      獲得前臺定位授權(quán)

case
kCLAuthorizationStatusAuthorizedWhenInUse:

{

      NSLog(@"獲得前臺定位授權(quán)");

 
  break;

}

default:

  break;

}

}

  1. 測試環(huán)境:

  2. XCode版本無要求

  3. 模擬器選擇iOS8.0之后的版本

  1. 常見問題總結(jié)

  2. 定位不到, 對應(yīng)的代理方法不執(zhí)行

首先,檢查是否請求授權(quán), 并設(shè)置了對應(yīng)的KEY

其次,檢查模擬器是否設(shè)置位置數(shù)據(jù)

第三,確保代碼無問題(一般都是代理沒有設(shè)置,或者位置管理器對象是局部變量,亦或是位置管理器對象沒有被強(qiáng)引用)

第四,絕逼是模擬器BUG, 請重置模擬器(是重置,不是重啟)

三. iOS9.0 定位補(bǔ)充(???)

  1. 定位變化
  • 前臺定位

(同iOS8.0之后一致, 無任何變化,
都需要主動請求授權(quán))

  • 后臺定位

方案一:

  1. 在前臺定位基礎(chǔ)上,
    勾選后臺模式Location updates, 并且設(shè)置以下屬性為YES

if ([[UIDevice currentDevice].systemVersion
floatValue] >= 9.0)

{

一個布爾值,該值指示是否應(yīng)用程序想要接收位置更新時暫停赏酥。

 self.locationM.allowsBackgroundLocationUpdates

= YES;

}

方案二:

  1. 請求前后臺定位授權(quán),并在info.plist文件中配置KEY ( NSLocationAlwaysUsageDescription )

[self.locationM requestAlwaysAuthorization];

  1. 新的API

  2. 單次定位請求;

代 碼: [self.locationM requestLocation];

功 能: 獲取一次位置信息

實(shí)現(xiàn)邏輯:

(1) 按照定位精確度從低到高進(jìn)行排序匆赃,逐個進(jìn)行定位.如果在有效時間內(nèi), 定位到了精確度最好的位置, 那么就把對應(yīng)的位置通過代理告知外界.

(2) 如果獲取到的位置不是精確度最高的那個,也會在定位超時后今缚,通過代理告訴外界.

注意事項(xiàng):

(1) 必須實(shí)現(xiàn)代理的-locationManager:didFailWithError:方法

(2) 不能與startUpdatingLocation方法同時使用

  1. 測試環(huán)境:

  2. XCode版本要求7.0版本以上

  3. 模擬器選擇iOS9.0之后的版本

  1. 常見問題總結(jié)

  2. 單次定位在模擬器上測試不出效果?

答: 因?yàn)槟M器的位置是固定的, 所以無法測試出效果, 請使用真機(jī)進(jìn)行測試.

四. CLLocation對象詳解(?????)

  1. 屬性解釋

coordinate : 當(dāng)前位置所在的經(jīng)緯度數(shù)據(jù)

altitude : 海拔

speed : 當(dāng)前速度

course : 航向(設(shè)備移動的方向, 值域范圍:0.0 ~ 259.9, 正北方向?yàn)?.0)

  1. 重要方法

代碼: -
(CLLocationDistance)distanceFromLocation:(CLLocation *)location

作用: 計算兩個位置對象之間的物理距離, 單位是(米)

  1. 場景演練

  2. 場景演示:打印當(dāng)前用戶的行走方向,偏離角度以及對應(yīng)的行走距離,

例如:”北偏東30度方向,移動了8米”

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

1> 獲取對應(yīng)的方向偏向(例如”正東”,”東偏南”)

2> 獲取對應(yīng)的偏離角度(并判斷是否是正方向)

3> 計算行走距離

4> 打印信息

  1. 注意事項(xiàng)

  2. 使用位置前,
    務(wù)必判斷當(dāng)前獲取的位置是否有效

代碼: if(location.horizontalAccuracy < 0) return;

功能: 如果水平精確度小于零, 代表雖然可以獲取位置對象, 但是數(shù)據(jù)錯誤, 不可用

經(jīng)驗(yàn)小結(jié)(??)

一. 定位的應(yīng)用場景

  1. 導(dǎo)航

  2. 電商APP,獲取用戶所在城市(需要與(反)地理編碼聯(lián)合使用)

  3. 數(shù)據(jù)采集用戶信息(例如,統(tǒng)計app使用分布)

  4. 查找周邊(周邊好友, 周邊商家等等)

二. 開發(fā)經(jīng)驗(yàn)

** 由于定位非常耗電;
所以為了給用戶省電, 你可以遵守以下小經(jīng)驗(yàn)**

1)不需要獲取用戶位置時,一定要關(guān)閉定位服務(wù):

2)如果能滿足項(xiàng)目需求,盡可能的使用”監(jiān)聽顯著位置變化”的定位服務(wù)(打車app)

3)如果可以,盡可能使用低精度的desiredAccuracy

4)如果是數(shù)據(jù)采集,(一般都是周期性的去輪詢用戶位置),在輪詢期間一定要關(guān)閉定位

五. 指南針效果實(shí)現(xiàn)(??)

  1. 實(shí)現(xiàn)思路

  2. 利用"磁力計"傳感器,獲取設(shè)備朝向

  3. 根據(jù)設(shè)備朝向反向旋轉(zhuǎn)"指南針"圖片

  1. 代碼實(shí)現(xiàn)

  2. 獲取設(shè)備朝向

  1. 導(dǎo)入CoreLocation框架以及對應(yīng)的主頭文件

import <CoreLocation/CoreLocation.h>

  1. 創(chuàng)建CLLocationManager對象并設(shè)置代理

self.locationM = [[CLLocationManager alloc] init];

self.locationM.delegate = self;

  1. 調(diào)用方法, 開始獲取設(shè)備朝向

[self.locationM startUpdatingHeading];

  1. 在對應(yīng)的代理方法中獲取設(shè)備朝向信息

-(void)locationManager:(CLLocationManager *)manager
didUpdateHeading:(CLHeading *)newHeading

{

旋轉(zhuǎn)圖片代碼

}

  1. 旋轉(zhuǎn)圖片

1.判斷當(dāng)前的角度是否有效(如果此值小于0,代表角度無效)

if(newHeading.headingAccuracy < 0)

return;

2.獲取當(dāng)前設(shè)備朝向(磁北方向)

CGFloat angle =
newHeading.magneticHeading;

3.轉(zhuǎn)換成為弧度

CGFloat radian = angle
/ 180.0 * M_PI;

4.帶動畫反向旋轉(zhuǎn)指南針

[UIView
animateWithDuration:0.5 animations:^{

self.compassView.transform =
CGAffineTransformMakeRotation(-radian);

}];

  1. 概念補(bǔ)充

磁北角度: newHeading.magneticHeading ------- 相對于"磁北方向"產(chǎn)生的角度

真北角度: newHeading.trueHeading ------- 相對于"真北方向"產(chǎn)生的角度

  1. 注意事項(xiàng)

  2. 獲取設(shè)備朝向前,
    先判斷"磁力計"是否可用

[CLLocationManager
headingAvailable];

  1. 獲取朝向前,
    判斷當(dāng)前朝向信息是否有效

if(newHeading.headingAccuracy < 0)return;

  1. 注意與"航向"的區(qū)別

設(shè)備朝向是指手機(jī)的朝向; "航向"可以理解為設(shè)備的移動方向

  1. 使用"磁力計"傳感器獲取設(shè)備朝向, 不需要請求用戶授權(quán)

因?yàn)樵O(shè)備朝向不涉及用戶隱私

5.測試環(huán)境

  1. XCode版本無要求(建議:XCode7.0不需要開發(fā)者賬號也可以進(jìn)行真機(jī)調(diào)試)

  2. 必須要求真機(jī)設(shè)備(只有真機(jī)設(shè)備才有"磁力計"傳感器)

六. 區(qū)域監(jiān)聽(???)

1.概念解釋

區(qū) 域: 就是指劃定的一塊地域范圍(比如圓形區(qū)域, 則由區(qū)域中心, 和半徑組成)

區(qū)域監(jiān)聽: 是指,我們通過代碼指定一個區(qū)域, 然后當(dāng)用戶持握設(shè)備進(jìn)入或者離開指定區(qū)域, 我們都能監(jiān)聽到.

  1. 監(jiān)聽指定區(qū)域
  1. 導(dǎo)入CoreLocation框架以及對應(yīng)的主頭文件

import <CoreLocation/CoreLocation.h>

  1. 創(chuàng)建CLLocationManager對象并設(shè)置代理

self.locationM = [[CLLocationManager alloc] init];

self.locationM.delegate = self;

  1. 請求前后臺定位,
    或前臺定位授權(quán), 并在Info.Plist文件中配置相應(yīng)的Key

[self.locationM requestAlwaysAuthorization];

[self.locationM
requestWhenInUseAuthorization];

  1. 創(chuàng)建一個區(qū)域,
    并開始監(jiān)聽
  1. 判斷區(qū)域監(jiān)聽服務(wù)是否可用(定位服務(wù)是否關(guān)閉, 定位是否授權(quán), 是否開啟飛行模式)

if ([CLLocationManager
isMonitoringAvailableForClass:[CLCircularRegion class]])

{

創(chuàng)建區(qū)域中心

CLLocationCoordinate2D center = CLLocationCoordinate2DMake(29.12345,
131.23456);

創(chuàng)建區(qū)域(指定區(qū)域中心算柳,和區(qū)域半徑)

CLLocationDistance radius = 1000;

判斷區(qū)域半徑是否大于最大監(jiān)聽區(qū)域半徑,如果大于, 就沒法監(jiān)聽

if (radius > self.locationM.maximumRegionMonitoringDistance)
{

radius = self.locationM.maximumRegionMonitoringDistance;

}

CLCircularRegion *region = [[CLCircularRegion alloc]
initWithCenter:center radius:radius identifier:@"小碼哥"];

開始監(jiān)聽指定區(qū)域

[self.locationM startMonitoringForRegion:region];

}

else

{

NSLog(@"區(qū)域監(jiān)聽不可用");

}

  1. 在對應(yīng)的代理方法中監(jiān)聽區(qū)域狀態(tài)

進(jìn)去監(jiān)聽區(qū)域后調(diào)用(調(diào)用一次)

-(void)locationManager:(nonnull
CLLocationManager *)manager didEnterRegion:(nonnull
CLRegion *)region

{

NSLog(@"進(jìn)入?yún)^(qū)域---%@", region.identifier);

[manager

stopMonitoringForRegion:region];

}

離開監(jiān)聽區(qū)域后調(diào)用(調(diào)用一次)

-(void)locationManager:(nonnull
CLLocationManager *)manager didExitRegion:(nonnull
CLRegion *)region

{

NSLog(@"離開區(qū)域---%@", region.identifier);

}

  1. 獲取某個區(qū)域的當(dāng)前狀態(tài)

監(jiān)聽某個區(qū)域時,
只有進(jìn)入或者離開這個區(qū)域時, 才能回調(diào)對應(yīng)的方法, 是一個進(jìn)入或者離開的動作

如果想知道某一個區(qū)域的當(dāng)前狀態(tài)(識別用戶是在區(qū)域內(nèi)部, 還是區(qū)域外部), 則需要使用以下方法

代 碼:

[self.locationM requestStateForRegion:region];

回調(diào)代理:

請求某個區(qū)域狀態(tài)時, 回調(diào)的代理方法

-(void)locationManager:(CLLocationManager *)manager
didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region

{

switch (state) {

case CLRegionStateUnknown:

      NSLog(@"未知狀態(tài)");

 
  break;

case CLRegionStateInside:

      NSLog(@"在區(qū)域內(nèi)部");

 
  break;

case CLRegionStateOutside:

      NSLog(@"在區(qū)域外部");

 
  break;

default:

  break;

}

}

  1. 測試環(huán)境

XCode版本無要求

iOS模擬器版本無要求

  1. 注意事項(xiàng)

  2. 想要做區(qū)域監(jiān)聽,
    在iOS8.0之后, 必須請求位置授權(quán)

代碼: [self.locationM requestAlwaysAuthorization];

原因: 區(qū)域監(jiān)聽的原理就是獲取用戶的位置, 然后在判斷該位置是否在制定區(qū)域內(nèi), 所以會涉及到用戶隱私(位置), 而在iOS8.0之后, 想要訪問用戶位置信息, 就需要主動請求授權(quán);

  1. 使用前, 先判斷區(qū)域監(jiān)聽是否可用

代碼: [CLLocationManager
isMonitoringAvailableForClass:[CLCircularRegion class]]

  1. 注意區(qū)域半徑是否大于最大區(qū)域監(jiān)聽半徑(如果大于, 則無法監(jiān)聽成功)

代碼: radius > self.locationM.maximumRegionMonitoringDistance

  1. 常見問題

  2. 區(qū)域監(jiān)聽, 測試沒有效果?

首先, 確定代碼沒有問題, 是否有請求授權(quán);

其次, 嘗試修改模擬器位置信息, 觸發(fā)進(jìn)入?yún)^(qū)域或離開區(qū)域的動作

第三, 如果模擬器出現(xiàn)BUG, 定位不到, 也會無法判定當(dāng)前區(qū)域狀態(tài); 所以, 最后可以嘗試重置模擬器.

七. (反)地理編碼(?????)

  1. 概念解釋

地理編碼: 是指根據(jù)地址關(guān)鍵字, 將其轉(zhuǎn)換成為對應(yīng)的經(jīng)緯度等信息;

發(fā)地理編碼: 是指根據(jù)經(jīng)緯度信息, 將其轉(zhuǎn)換成為對應(yīng)的省市區(qū)街道等信息;

  1. 地理編碼

  2. 導(dǎo)入CoreLocation框架以及對應(yīng)的主頭文件

import <CoreLocation/CoreLocation.h>

  1. 創(chuàng)建CLGeocoder對象

self.geoC = [[CLGeocoder alloc] init];

  1. 根據(jù)地址關(guān)鍵字,
    進(jìn)行地理編碼

直接根據(jù)地址進(jìn)行地理編碼(返回結(jié)果可能有多個,因?yàn)橐粋€地點(diǎn)有重名)

[self.geoC geocodeAddressString:@"廣州" completionHandler:^(NSArray<CLPlacemark *> * __nullableplacemarks, NSError * __nullable error)

{

 包含區(qū)姓言,街道等信息的地標(biāo)對象

CLPlacemark *placemark = [placemarks firstObject];

 城市名稱

NSString *city = placemark.locality;

 街道名稱

NSString *street = placemark.thoroughfare;

全稱

NSString *name = placemark.name;

}];

  1. 反地理編碼

  2. 導(dǎo)入CoreLocation框架以及對應(yīng)的主頭文件

import <CoreLocation/CoreLocation.h>

  1. 創(chuàng)建CLGeocoder對象

self.geoC = [[CLGeocoder alloc] init];

  1. 根據(jù)經(jīng)緯度信息,
    進(jìn)行反地理編碼

根據(jù)經(jīng)緯度信息進(jìn)行反地理編碼

[self.geoC reverseGeocodeLocation:[[CLLocation
alloc] initWithLatitude:21.123 longitude:123.345]
completionHandler:^(NSArray<CLPlacemark *> * __nullable
placemarks, NSError * __nullable error)

{

 包含區(qū)瞬项,街道等信息的地標(biāo)對象

CLPlacemark *placemark = [placemarks firstObject];

 城市名稱

NSString *city = placemark.locality;

 街道名稱

NSString *street = placemark.thoroughfare;

全稱

NSString *name = placemark.name;

}];

CLPlacemark 地標(biāo)對象詳解

location
: CLLocation 類型, 位置對象信息, 里面包含經(jīng)緯度, 海拔等等

region :
CLRegion 類型, 地標(biāo)對象對應(yīng)的區(qū)域

addressDictionary
: NSDictionary 類型, 存放街道,省市等信息

name :
NSString 類型, 地址全稱

thoroughfare
: NSString 類型, 街道名稱

locality
: NSString 類型, 城市名稱

administrativeArea
: NSString 類型, 省名稱

country
: NSString 類型, 國家名稱

  1. 測試環(huán)境
  • 必須聯(lián)網(wǎng)

XCode版本不限

iOS模擬器系統(tǒng)版本不限

  1. 常見問題

  2. 測試無數(shù)據(jù)?

首先, 檢查是否有聯(lián)網(wǎng);

其次, 如果是反地理編碼,可嘗試更換經(jīng)緯度再次嘗試, 有的經(jīng)緯度沒有對應(yīng)信息

  1. 應(yīng)用場景

  2. 一般與定位結(jié)合使用, 確定當(dāng)前位置的具體地理信息

八. 使用第三方框架進(jìn)行定位(??)

  1. 主要原因

因?yàn)槭褂肅oreLocation框架進(jìn)行獲取用戶位置信息, 是通過代理進(jìn)行回調(diào); 而第三方框架將"代理模擬"轉(zhuǎn)換成為"block模式"; 使用起來比較方便, 而且額外增加了超時時間等功能.

  1. 框架信息

名稱: locationManager

地址:
link

  1. 使用方法
    參照該框架對應(yīng)的readME
  1. 注意事項(xiàng)
    一般集成第三方框架到項(xiàng)目中, 請先確保該框架沒有問題, 然后再向項(xiàng)目中集成

九. 補(bǔ)充(???)

    1. 代理模式到block模式的轉(zhuǎn)換

 
 


    主要思想就是,先記錄下外界傳遞過來的block, 然后在對應(yīng)的代理方法里面執(zhí)行這個block;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市何荚,隨后出現(xiàn)的幾起案子囱淋,更是在濱河造成了極大的恐慌,老刑警劉巖餐塘,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妥衣,死亡現(xiàn)場離奇詭異,居然都是意外死亡戒傻,警方通過查閱死者的電腦和手機(jī)税手,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來需纳,“玉大人芦倒,你說我怎么就攤上這事〔霍妫” “怎么了兵扬?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵麻裳,是天一觀的道長。 經(jīng)常有香客問我器钟,道長津坑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任傲霸,我火速辦了婚禮国瓮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘狞谱。我一直安慰自己乃摹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布跟衅。 她就那樣靜靜地躺著孵睬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪伶跷。 梳的紋絲不亂的頭發(fā)上掰读,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音叭莫,去河邊找鬼蹈集。 笑死,一個胖子當(dāng)著我的面吹牛雇初,可吹牛的內(nèi)容都是我干的拢肆。 我是一名探鬼主播挺庞,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼新症,長吁一口氣:“原來是場噩夢啊……” “哼芙盘!你這毒婦竟也來了族跛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤尉姨,失蹤者是張志新(化名)和其女友劉穎我擂,沒想到半個月后择吊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體促绵,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡攒庵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了败晴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浓冒。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖位衩,靈堂內(nèi)的尸體忽然破棺而出裆蒸,到底是詐尸還是另有隱情熔萧,我是刑警寧澤糖驴,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布僚祷,位于F島的核電站,受9級特大地震影響贮缕,放射性物質(zhì)發(fā)生泄漏辙谜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一感昼、第九天 我趴在偏房一處隱蔽的房頂上張望装哆。 院中可真熱鬧,春花似錦定嗓、人聲如沸蜕琴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凌简。三九已至,卻和暖如春恃逻,著一層夾襖步出監(jiān)牢的瞬間雏搂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工寇损, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凸郑,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓矛市,卻偏偏與公主長得像芙沥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子浊吏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

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

  • CoreLocation框架 一. iOS8.0之前的定位(?????) 前臺定位導(dǎo)入CoreLocation框架...
    尼古拉斯趙四爺閱讀 972評論 0 2
  • CoreLocation框架 一. iOS8.0之前的定位 1. 前臺定位 導(dǎo)入CoreLocation框架以及對...
    iOS_Cqlee閱讀 1,376評論 1 2
  • 片頭曲 CoreLocation框架 來自520it.com 一. iOS8.0之前的定位(?????) 1. 前...
    人生路02閱讀 346評論 0 1
  • 一. iOS8.0之前的定位(?????) 1. 前臺定位 導(dǎo)入CoreLocation框架以及對應(yīng)的主頭文件 #...
    走道牙的人閱讀 238評論 0 0
  • 來到大理卿捎,歲月如梭配紫。轉(zhuǎn)瞬將近一年,雖曾多次在下關(guān)的風(fēng)裡走過午阵,去擁抱美麗的日出躺孝,但都少了那份安靜,愜意無存底桂,也就不盡...
    秦塬牛閱讀 468評論 0 3