我目前正在监控几个由核心数据支持的位置。换句话说,我已经设置了一个for循环,该循环遍历core data中所有存储的实体,并为所有实体创建一个受监视的区域。
这里的问题是,当进入一个区域时,for循环触发多个本地通知。通知的数量几乎直接对应于监控区域的数量。所以我相当确信这可能是导致bug的原因,但我不是百分之百确定。
我注意到这似乎是区域监控的一个常见问题,但我没有找到一个包含for循环的例子。
我如何阻止多个通知被触发时,didEnterRegion被调用?
下面的方法在viewDidLoad中被调用。[DataSource shareinstance]。fetchedResultItems是一个数组,由一个获取请求的fetcheddobjects填充。
-(void)startMonitoringRegions{
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
CLAuthorizationStatus authorizationStatus = [CLLocationManager authorizationStatus];
if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways ||
authorizationStatus == kCLAuthorizationStatusAuthorizedWhenInUse) {
self.locationManager.distanceFilter = 10;
[self.locationManager startUpdatingLocation];
for (POI *items in [DataSource sharedInstance].fetchResultItems){
NSString *poiName = items.name;
NSNumber *poiLatitude = items.yCoordinate;
NSLog(@"value: %@", poiLatitude);
NSNumber *poiLongitude = items.xCoordinate;
NSLog(@"value: %@", poiLongitude);
NSString *identifier = poiName;
CLLocationDegrees latitude = [poiLatitude floatValue];
CLLocationDegrees longitude = [poiLongitude floatValue];
CLLocationCoordinate2D centerCoordinate = CLLocationCoordinate2DMake(latitude, longitude);
self.regionRadius = 10;
self.region = [[CLCircularRegion alloc] initWithCenter:centerCoordinate radius:400 identifier:identifier];
[self.locationManager startMonitoringForRegion:self.region];
NSLog(@"region: %@", self.region);
NSLog(@"monitored regions %@", self.locationManager.monitoredRegions);
}
}
}
}
下面是didEnterRegion方法
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
NSLog(@"entered region!!");
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
if (localNotification) {
localNotification.fireDate = nil;
localNotification.alertBody = [NSString stringWithFormat:@"You are near %@", self.region.identifier];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
localNotification.timeZone = [NSTimeZone defaultTimeZone];
}
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
// [[UIApplication sharedApplication]presentLocalNotificationNow:localNotification];
}
区域作为共享资源。当您进入任何区域时,呼叫将被转发到所有位置管理器。我认为你在某处创建了多个位置管理器对象。那会导致多次调用didEnterRegion。didEnterRegion被调用的次数取决于你注册的LocationManager的数量。你应该在AppDelegate中编写代码,在这个方法
中- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//把你的代码放在这里
}
只是一个故障排除提示。你可以使用Obj-C等价于以下内容来查看应用程序当前正在监控哪些区域。也许检查标识符将有助于解决问题。
for region in locationManager.monitoredRegions {
debugPrint(region.identifier)
}
为了一个干净的开始,你可以删除所有的区域:
for region in locationManager.monitoredRegions {
locationManager.stopMonitoringForRegion(region)
}