一藤违、基本步驟
-
1.導(dǎo)入CoreLocation框架和對應(yīng)的主頭文件
#import <CoreLocation/CoreLocation.h>
-
2.創(chuàng)建CLLcationManager對象,并設(shè)置代理,請求授權(quán)(iOS8.0之后才需要)憔儿,請求前后臺定位授權(quán),并配置KEY
pragma mark -懶加載
-(CLLocationManager *)locationM
{
if (!_locationM) {
_locationM = [[CLLocationManager alloc] init];
_locationM.delegate = self;
// 主動請求定位授權(quán)
if([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
[_locationM requestAlwaysAuthorization];
}
return _locationM;
}
+ 3.調(diào)用CLLcationManager對象的startMonitoringForRegion:方法進行監(jiān)聽指定區(qū)域
```objc
// 0. 創(chuàng)建一個區(qū)域
// 1.確定區(qū)域中心
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(101.123, 20.345);
// 確定區(qū)域半徑
CLLocationDistance radius = 1000;
// 使用前必須判定當(dāng)前的監(jiān)聽區(qū)域半徑是否大于最大可被監(jiān)聽的區(qū)域半徑
if(radius > self.locationM.maximumRegionMonitoringDistance)
{
radius = self.locationM.maximumRegionMonitoringDistance;
}
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center radius:radius identifier:@"JP"];
// 區(qū)域監(jiān)聽
// [self.locationM startMonitoringForRegion:region];
// 請求區(qū)域狀態(tài)(如果發(fā)生了進入或者離開區(qū)域的動作也會調(diào)用對應(yīng)的代理方法)
[self.locationM requestStateForRegion:region];
- 4.實現(xiàn)代理方法,獲取區(qū)域進入或者離開等狀態(tài)
#pragma mark -CLLocationManagerDelegate
/**
* 進入?yún)^(qū)域調(diào)用(是一個動作)
*
* @param manager 位置管理者
* @param region 區(qū)域
*/
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(@"進入?yún)^(qū)域");
self.noticeLabel.text = @"進入?yún)^(qū)域";
}
/**
* 離開某個區(qū)域調(diào)用
*
* @param manager 位置管理者
* @param region 區(qū)域
*/
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
NSLog(@"離開區(qū)域");
self.noticeLabel.text = @" 離開某個區(qū)域";
}
/**
* 請求某個區(qū)域的狀態(tài)是調(diào)用
*
* @param manager 位置管理者
* @param state 狀態(tài)
* @param region 區(qū)域
*/
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
// CLRegionStateUnknown, 未知狀態(tài)
// CLRegionStateInside, // 在區(qū)域內(nèi)部
// CLRegionStateOutside // 區(qū)域外面
if(state == CLRegionStateInside)
{
self.noticeLabel.text = @"在區(qū)域內(nèi)部";
}else if (state == CLRegionStateOutside)
{
self.noticeLabel.text = @"區(qū)域外面";
}
}
/**
* 監(jiān)聽區(qū)域失敗時調(diào)用
*
* @param manager 位置管理者
* @param region 區(qū)域
* @param error 錯誤
*/
-(void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
{
// 經(jīng)驗: 一般在這里, 做移除最遠的區(qū)域
// [manager stopMonitoringForRegion:最遠區(qū)域]
}
二、注意
- 1.使用前先判斷區(qū)域監(jiān)聽是否可用
- 2.注意監(jiān)聽區(qū)域的個數(shù) (區(qū)域監(jiān)聽個數(shù)有上限)
- 3.注意區(qū)域半徑是否大于最大監(jiān)聽半徑
三、應(yīng)用場景
- 1.結(jié)合推送通知使用,可以當(dāng)用戶進入到某個區(qū)域內(nèi)(例如肯德基)之后,向用戶推送優(yōu)惠卡等信息
四夯膀、實現(xiàn)代碼
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
@interface ViewController ()<CLLocationManagerDelegate>
/** 位置管理者 */
@property (nonatomic, strong) CLLocationManager *locationM;
@property (weak, nonatomic) IBOutlet UILabel *noticeLabel;
@end
@implementation ViewController
#pragma mark -懶加載
-(CLLocationManager *)locationM
{
if (!_locationM) {
_locationM = [[CLLocationManager alloc] init];
_locationM.delegate = self;
// 主動請求定位授權(quán)
if([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
[_locationM requestAlwaysAuthorization];
}
return _locationM;
}
- (void)viewDidLoad {
/** 如果想要區(qū)域監(jiān)聽, 必須獲取用戶的定位授權(quán) */
// 監(jiān)聽的區(qū)域個數(shù)有限制
// 判定某個區(qū)域?qū)?yīng)的類, 能否被監(jiān)聽
if([CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]])
{
// 0. 創(chuàng)建一個區(qū)域
// 1.確定區(qū)域中心
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(101.123, 20.345);
// 確定區(qū)域半徑
CLLocationDistance radius = 1000;
// 使用前必須判定當(dāng)前的監(jiān)聽區(qū)域半徑是否大于最大可被監(jiān)聽的區(qū)域半徑
if(radius > self.locationM.maximumRegionMonitoringDistance)
{
radius = self.locationM.maximumRegionMonitoringDistance;
}
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center radius:radius identifier:@"JP"];
// 區(qū)域監(jiān)聽
// [self.locationM startMonitoringForRegion:region];
// 請求區(qū)域狀態(tài)(如果發(fā)生了進入或者離開區(qū)域的動作也會調(diào)用對應(yīng)的代理方法)
[self.locationM requestStateForRegion:region];
}
}
#pragma mark -CLLocationManagerDelegate
/**
* 進入?yún)^(qū)域調(diào)用(是一個動作)
*
* @param manager 位置管理者
* @param region 區(qū)域
*/
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(@"進入?yún)^(qū)域");
self.noticeLabel.text = @"進入?yún)^(qū)域";
}
/**
* 離開某個區(qū)域調(diào)用
*
* @param manager 位置管理者
* @param region 區(qū)域
*/
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
NSLog(@"離開區(qū)域");
self.noticeLabel.text = @"離開區(qū)域";
}
/**
* 請求某個區(qū)域的狀態(tài)是調(diào)用
*
* @param manager 位置管理者
* @param state 狀態(tài)
* @param region 區(qū)域
*/
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
// CLRegionStateUnknown, 未知狀態(tài)
// CLRegionStateInside, // 在區(qū)域內(nèi)部
// CLRegionStateOutside // 區(qū)域外面
if(state == CLRegionStateInside)
{
self.noticeLabel.text = @"在區(qū)域內(nèi)部";
}else if (state == CLRegionStateOutside)
{
self.noticeLabel.text = @"區(qū)域外面";
}
}
/**
* 監(jiān)聽區(qū)域失敗時調(diào)用
*
* @param manager 位置管理者
* @param region 區(qū)域
* @param error 錯誤
*/
-(void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
{
// 經(jīng)驗: 一般在這里, 做移除最遠的區(qū)域
// [manager stopMonitoringForRegion:最遠區(qū)域]
}
@end