【发布时间】:2014-05-04 16:45:24
【问题描述】:
我有一个 iBeacons 应用程序,能够在后台或未运行时测量信标范围。我实现了UILocalNotifications,它们工作正常,这意味着当我到达信标的范围时我会收到通知。
没有真正的信标我创建了一个应用程序(对于另一台设备,让我们说一个 iPad 用于下一个场景)就像 2 个不同的信标,这意味着它可以广播 2 个不同的信号,相同 @ 987654323@ 但不同的 Major/Minor 值(称为此信标 A 和 B),显然一次一个。我的问题是在这种情况下:
- 让我的 iPhone(关闭 iBeacons 应用程序)处于锁定屏幕状态
- 激活我的 iPad 应用,广播信标 A
- 我的 iPhone 做出反应,向我显示通知
- 我停止 iPad 应用程序广播信标 A,等待 1 秒,开始广播信标 B
- 我的 iPhone 没有反应
- 我停止 iPad 广播
- 几分钟后(大约 2 分钟)我的 iPhone 向我显示信标 B 的通知
现在我不明白的是这种延迟,第一次我的 iPhone 立即反应,第二次大约需要 2 分钟通知我信标。
如果在信标 B 通知之后,我重新开始广播信标(A 或 B),我的 iPhone 会立即做出反应,那么下一次它总是等待 2 分钟。
为什么会这样?我读过一些文章说这是因为蓝牙在应用程序处于后台时每 2-4 分钟唤醒一次,所以我不能比这个时间更快地获取信息。但我认为这没有多大意义,因为每当我收到 second 通知时,信标的广播(在我的场景中为 B)已经 停止 strong>,这意味着如果蓝牙在那一刻醒来,空中就没有信标!但是我收到了通知,所以这意味着我的 iPhone 在我停止广播之前发现了它。
这是一个可以解决的问题吗?
用一些代码编辑
这是我的viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
// Initialize location manager and set ourselves as the delegate and beacons dictionary
_beacons = [[NSMutableDictionary alloc] init];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// Create a NSUUID with the same UUID as the broadcasting beacon
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"6C1AA496-1653-403D-BD1E-7F630AA6F254"];
// Setup a new region with that UUID and same identifier as the broadcasting beacon
self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
identifier:@"testregion"];
NSLog(@"startMonitoring");
// Tell location manager to start monitoring for the beacon region
[self.locationManager startMonitoringForRegion:self.myBeaconRegion];
[self.locationManager startRangingBeaconsInRegion:self.myBeaconRegion];
_myBeaconRegion.notifyEntryStateOnDisplay = YES;
// Check if beacon monitoring is available for this device
if (![CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]]){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Monitoring not available" message:nil delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil]; [alert show]; return;
}
}
现在每当我收到信标时,我都会发送通知,我只是想尝试一下它是如何工作的,所以我还没有实现只发送 1 个通知的方法,这意味着我收到大约 9 个通知,每秒 1 个我想代码可以在后台运行的活动时间(进入区域 1 秒,信标测距 9 秒)
-(void)locationManager:(CLLocationManager*)manager
didRangeBeacons:(NSArray*)beacons
inRegion:(CLBeaconRegion*)region
{
if([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground){
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = @"Found Beacon";
notification.soundName = @"Default";
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
}
实际上,更具体地说,如果我从多任务视图中完全关闭我的应用程序,或者只是让它在后台运行,一旦我开始广播信标,我就会收到通知**S**(延迟 1 秒)。然后停止广播并重新播放延迟变为以分钟为单位。
现在对于一个真实的场景,我应该在同一个地方有许多信标,这种延迟可能是一个问题,只要我在可能已经远离信标本身时收到通知。
我的代码有问题吗?我阅读了那些文章,但我从未发现延迟 15 分钟。
在 davidgyoung 建议后编辑 2
我修改了我的代码,正如您所说,为信标 A 和 B 使用 2 个不同的区域,延迟始终为空。我还记录了您提供的代码,我发现了这一点。
- 广播
Region_1的信标 - 设备向我显示
Region_1的通知 - 停止广播
Region_1的信标 - 日志说我还在该地区,几分钟后我得到日志“OUTSIDE
Region_1”,刚才我可以重新播放广播以从Region_1获得另一个通知。
所以我对此很好奇,我阅读了http://beekn.net/2014/03/apple-ios-7-1-launches-major-ibeacon-improvement/的文章
作者说,从 iOS 7.1 开始,退出区域的响应是即时的,实际上我正在运行 7.1,但我也有几分钟的延迟。为什么这个?您是否在测试中发现了同样的问题?
现在,我读到一个设备最多只能监听 20 个区域,对吧?这意味着如果我有 100 个信标,我可以只设置 20 个区域并将这 100 个区域分成 20 个组,得到的通知不超过 20 个(假设这 100 个在同一个地方,都在我的设备范围内)?这可能是一个问题,因为这将迫使用户在前台运行应用程序以获取所有信息(再次假设 100 个信标中的每一个都具有特定的单元角色),对吗?
【问题讨论】:
-
如果您跳过第 6 步。第 7 步是否会发生?
-
是的,几分钟后我还是收到了通知
-
即使使用 iOS7.1,后台检测也不是即时的,可能需要几分钟。我什至发布了证明! (请参阅我的第一个答案中的链接。)。是的,iOS 将您限制为 20 个监控区域,因此您必须谨慎设置。如果可以,请确定您将在其中传输重叠的信标 ID,并为它们使用单独的区域。 (或者只是忍受多个信标被视为一个区域的限制。)
标签: ios iphone bluetooth ibeacon