一、简介
开发时遇到一个需求,快到家时App提醒用户,做相应的操作。经研究,发现OC的电子围栏技术能够满足自己的需求,于是写了一个 Demo,做个记录,也和大家分享一下。
区域监测,也称地理围栏,或者临近警告。如果希望iOS设备进出某个区域发出通知,那么这种区域监测的功能也被称为临近警告。此功能实现的是:首先创建一个区域(围栏),当用户设备进入或者离开此区域时,会有相应的代理方法响应,开发者可以做一些操作。并且最重要的一点是当开启了区域监控,即使用户杀死了APP还是可以监听到代理方法的响应,从而做一些操作。
区域监测我们3种方法完成,第一种是OC自有的,利用CLLocationManager监测若干CLCircularRegion区域,第二种是集高德地图的功能,第三种是集成百度地图的功能。本文主要介绍OC自有的功能,介绍原理使用。
二、具体实现
1、开启后台定位功能
2、配置Info.plist描述文件
Privacy - Location Always and When In Use Usage Description
Privacy - Location Always Usage Description
Privacy - Location When In Use Usage Description
3、初始化CLLocationManager
创建CLLocationManager对象,该对象负责获取定位相关信息,并为该对象设置一些必要的属性。
- (CLLocationManager *)locationMgr {
if (!_locationMgr) {
_locationMgr = [[CLLocationManager alloc] init];
_locationMgr.delegate = self;
_locationMgr.desiredAccuracy = kCLLocationAccuracyBest;
_locationMgr.distanceFilter = 10;
// 主动请求定位授权
[_locationMgr requestAlwaysAuthorization];
// 这是iOS9中针对后台定位推出的新属性 不设置的话 可是会出现顶部蓝条的哦(类似热点连接)
[_locationMgr setAllowsBackgroundLocationUpdates:YES];
_locationMgr.pausesLocationUpdatesAutomatically = NO;
}
return _locationMgr;
}
4、设置监听的位置
设置需要监听的地址位置,及监听的圆形区域,包括中心点几半径,可设置多个区域。
// 设置监听的位置
- (void)regionObserveWithLocation:(CLLocationCoordinate2D)location {
if (![CLLocationManager locationServicesEnabled]) {
NSLog(@"您的设备不支持定位");
return;
}
// 设置区域半径
CLLocationDistance radius = 200;
// 使用前必须判定当前的监听区域半径是否大于最大可被监听的区域半径
if(radius > self.locationMgr.maximumRegionMonitoringDistance) {
radius = self.locationMgr.maximumRegionMonitoringDistance;
}
// 设置id
NSString *identifier =
[NSString stringWithFormat:@"%f , %f", location.latitude, location.longitude];
// 使用CLCircularRegion创建一个圆形区域,
CLRegion *fkit = [[CLCircularRegion alloc] initWithCenter:location
radius:radius
identifier:identifier];
// 开始监听fkit区域
[self.locationMgr startMonitoringForRegion:fkit];
// 请求区域状态(如果发生了进入或者离开区域的动作也会调用对应的代理方法)
[self.locationMgr requestStateForRegion:fkit];
}
5、实现代理方法
当地址位置改变时,会代理方法的回调,包括进入区域、离开区域,及错误回调。CLLocationManagerDelegate
还有其他代理方法,这里就不多做介绍。
// 进入指定区域以后将弹出提示框提示用户
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSString *msg = [NSString stringWithFormat:@"进入指定区域 %@", region.identifier];
[self dealAlertWithStr:msg];
}
// 离开指定区域以后将弹出提示框提示用户
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
NSString *msg = [NSString stringWithFormat:@"离开指定区域 %@", region.identifier];
[self dealAlertWithStr:msg];
}
// 监听区域失败时调用
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error {
NSLog(@"监听区域失败 : %@", error);
}
6、开启监听
开启监听的方法,我放在的App启动的时候,为了能让程序被杀掉时也能触发通知。当用户设置始终访问地理位置权限时,即使App被杀死,当用户位置改变,进入或离开监控区域时都会唤醒App,会走 didFinishLaunchingWithOptions
方法。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self registerNotifaction];
[self awakeForRegionWithOptions:launchOptions];
return YES;
}
// APP被唤醒机制
- (void)awakeForRegionWithOptions:(NSDictionary *)launchOptions {
// 应用启动时开启监听
[[ZJHRegionManager shareInstance] starMonitorRegion];
// 被区域监测唤醒
// 我在模拟器测试,更改地理位置时,launchOptions数据为空
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) {
NSLog(@"区域监测唤醒");
}
}
三、测试验证
1、前台测试
可通过修改模拟的地址位置,测试位置变更
2、后台测试
想要杀掉App也能监控区域,要设置一下定位服务,选择“始终”。这里有个问题,就是杀掉app后,监听位置变更后,收到了两条推送。暂时还没定位到问题,知道原因的朋友,欢迎评论留言,多多指教。
3、可能会遇到的问题
- 与其他App中地理位置设置有冲突,导致设置位置失败。
- 与集成的百度地图或高德地图监控位置有冲突。
遇到问题不要慌,仔细排查,总是能解决的。祝君好运!🍺🍺🍺
参考链接:
Demo 下载
iOS地理围栏技术的应用
iOS区域监控(地理围栏)
iOS开发-电子围栏区域监听深入篇