iOS 区域监听
2015-11-12 本文已影响640人
iOS_成才录
一、基本步骤
-
1.导入CoreLocation框架和对应的主头文件
#import <CoreLocation/CoreLocation.h>
-
2.创建CLLcationManager对象,并设置代理,请求授权(iOS8.0之后才需要),请求前后台定位授权,并配置KEY
pragma mark -懒加载
-(CLLocationManager *)locationM
{
if (!_locationM) {
_locationM = [[CLLocationManager alloc] init];
_locationM.delegate = self;
// 主动请求定位授权
if([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
[_locationM requestAlwaysAuthorization];
}
return _locationM;
}
+ 3.调用CLLcationManager对象的startMonitoringForRegion:方法进行监听指定区域
```objc
// 0. 创建一个区域
// 1.确定区域中心
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(101.123, 20.345);
// 确定区域半径
CLLocationDistance radius = 1000;
// 使用前必须判定当前的监听区域半径是否大于最大可被监听的区域半径
if(radius > self.locationM.maximumRegionMonitoringDistance)
{
radius = self.locationM.maximumRegionMonitoringDistance;
}
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center radius:radius identifier:@"JP"];
// 区域监听
// [self.locationM startMonitoringForRegion:region];
// 请求区域状态(如果发生了进入或者离开区域的动作也会调用对应的代理方法)
[self.locationM requestStateForRegion:region];
- 4.实现代理方法,获取区域进入或者离开等状态
#pragma mark -CLLocationManagerDelegate
/**
* 进入区域调用(是一个动作)
*
* @param manager 位置管理者
* @param region 区域
*/
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(@"进入区域");
self.noticeLabel.text = @"进入区域";
}
/**
* 离开某个区域调用
*
* @param manager 位置管理者
* @param region 区域
*/
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
NSLog(@"离开区域");
self.noticeLabel.text = @" 离开某个区域";
}
/**
* 请求某个区域的状态是调用
*
* @param manager 位置管理者
* @param state 状态
* @param region 区域
*/
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
// CLRegionStateUnknown, 未知状态
// CLRegionStateInside, // 在区域内部
// CLRegionStateOutside // 区域外面
if(state == CLRegionStateInside)
{
self.noticeLabel.text = @"在区域内部";
}else if (state == CLRegionStateOutside)
{
self.noticeLabel.text = @"区域外面";
}
}
/**
* 监听区域失败时调用
*
* @param manager 位置管理者
* @param region 区域
* @param error 错误
*/
-(void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
{
// 经验: 一般在这里, 做移除最远的区域
// [manager stopMonitoringForRegion:最远区域]
}
二、注意
- 1.使用前先判断区域监听是否可用
- 2.注意监听区域的个数 (区域监听个数有上限)
- 3.注意区域半径是否大于最大监听半径
三、应用场景
- 1.结合推送通知使用,可以当用户进入到某个区域内(例如肯德基)之后,向用户推送优惠卡等信息
四、实现代码
#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;
// 主动请求定位授权
if([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
[_locationM requestAlwaysAuthorization];
}
return _locationM;
}
- (void)viewDidLoad {
/** 如果想要区域监听, 必须获取用户的定位授权 */
// 监听的区域个数有限制
// 判定某个区域对应的类, 能否被监听
if([CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]])
{
// 0. 创建一个区域
// 1.确定区域中心
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(101.123, 20.345);
// 确定区域半径
CLLocationDistance radius = 1000;
// 使用前必须判定当前的监听区域半径是否大于最大可被监听的区域半径
if(radius > self.locationM.maximumRegionMonitoringDistance)
{
radius = self.locationM.maximumRegionMonitoringDistance;
}
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center radius:radius identifier:@"JP"];
// 区域监听
// [self.locationM startMonitoringForRegion:region];
// 请求区域状态(如果发生了进入或者离开区域的动作也会调用对应的代理方法)
[self.locationM requestStateForRegion:region];
}
}
#pragma mark -CLLocationManagerDelegate
/**
* 进入区域调用(是一个动作)
*
* @param manager 位置管理者
* @param region 区域
*/
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(@"进入区域");
self.noticeLabel.text = @"进入区域";
}
/**
* 离开某个区域调用
*
* @param manager 位置管理者
* @param region 区域
*/
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
NSLog(@"离开区域");
self.noticeLabel.text = @"离开区域";
}
/**
* 请求某个区域的状态是调用
*
* @param manager 位置管理者
* @param state 状态
* @param region 区域
*/
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
// CLRegionStateUnknown, 未知状态
// CLRegionStateInside, // 在区域内部
// CLRegionStateOutside // 区域外面
if(state == CLRegionStateInside)
{
self.noticeLabel.text = @"在区域内部";
}else if (state == CLRegionStateOutside)
{
self.noticeLabel.text = @"区域外面";
}
}
/**
* 监听区域失败时调用
*
* @param manager 位置管理者
* @param region 区域
* @param error 错误
*/
-(void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
{
// 经验: 一般在这里, 做移除最远的区域
// [manager stopMonitoringForRegion:最远区域]
}
@end