CLProximityNear时显示背景通知

时间:2014-01-17 21:35:09

标签: ios7 core-location ibeacon

我正在尝试在我的应用程序处于后台并且设备进入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方法?

2 个答案:

答案 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参数的内容进行比较。然后,您应该能够判断是否找到了新的信标。