我正在尝试在我的应用程序处于后台并且设备进入iBeacon的区域时显示通知,并且当他们的CLProximity接近时,通知正在工作,但它始终以1秒的间隔出现:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
NSLog(@"Entered beacon region");
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
- (void) locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region{
NSLog(@"Left region");
[self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
}
- (void) locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
- (void) locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
CLBeacon *beacon = [[CLBeacon alloc] init];
beacon = [beacons lastObject];
self.uuidLabel.text = beacon.proximityUUID.UUIDString;
if(beacon.proximity == CLProximityUnknown) {
distanceLabel.text = @"Unknown Proximity";
[self.view setBackgroundColor:[UIColor grayColor]];
} else if (beacon.proximity == CLProximityImmediate) {
distanceLabel.text = @"Immediate";
[self.view setBackgroundColor:[UIColor redColor]];
} else if (beacon.proximity == CLProximityNear) {
distanceLabel.text = @"Near";
[self.view setBackgroundColor:[UIColor orangeColor]];
UILocalNotification *inRange = [[UILocalNotification alloc] init];
inRange.alertBody = [NSString stringWithFormat:@"Entered region!"];
inRange.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] presentLocalNotificationNow:inRange];
} else if (beacon.proximity == CLProximityFar) {
distanceLabel.text = @"Far";
[self.view setBackgroundColor:[UIColor blueColor]];
}
}
在显示通知后是否应该有一个方法调用告诉应用程序它已被显示,并且在用户超出范围并再次返回之前不要继续调用didRangeBeacons方法?
答案 0 :(得分:1)
可以像这样解决多个通知:
如果您只希望发送一次通知,只需定义一个alreadyDisplayed
标志,该标志在发送通知后设置,然后在发送之前检查其值。
像这样:
BOOL alreadyDisplayed = NO;
...
- (void) locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
...
else if (beacon.proximity == CLProximityNear) {
distanceLabel.text = @"Near";
if (!alreadyDisplayed) {
[self.view setBackgroundColor:[UIColor orangeColor]];
alreadyDisplayed = YES;
UILocalNotification *inRange = [[UILocalNotification alloc] init];
inRange.alertBody = [NSString stringWithFormat:@"Entered region!"];
inRange.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] presentLocalNotificationNow:inRange];
}
}
...
}
但您还有第二个问题:
如果您想在后台中执行此操作,正如您的问题标题所示,这根本不起作用。问题是,在iOS检测到您的手机在后台进入iBeacon区域后,它只能让它运行五秒钟才能进入睡眠状态。由于iBeacon的范围大约为50米,因此最可能的情况是,当您处于该50米范围的边缘时,此五秒间隔将开始。用户不太可能走得那么快,以至于他们在应用程序进入睡眠状态之前的5秒内进入“近”接近状态。因此,当您在后台时,通常无法根据特定距离采取特定行动。
也就是说,如果您想在前台执行此操作,如果您进行更改以防止通知每秒发生,这将正常工作。
答案 1 :(得分:1)
当测距信标时,每隔一秒就会调用locationManager:didRangeBeacons:inRegion
,正如您所识别的那样。每次beacons
参数都包含所有可见信标的数组。
由您的应用程序决定是否包含逻辑以确定新信标是否可见,或者您是否已经通知用户。我建议您存储一组先前发现的信标,每次调用locationManager:didRangeBeacons:inRegion
时,您都要将列表与beacons
参数的内容进行比较。然后,您应该能够判断是否找到了新的信标。