了解iOS中的iBeacon:didDetermineState和didEnterRegion事件 [英] Understanding iBeacons in iOS: didDetermineState and didEnterRegion events
问题描述
第一部分:
我编写了以下代码来监视iBeacons。我想检测 didEnterRegion 和 didExitRegion 事件。但是它永远不会发生。您是否可以看一下代码并提出可能遗漏的内容?
I have written the following code to monitor iBeacons. I would like to detect the didEnterRegion and didExitRegion event. However it never happens. Would you be able to take a look at the code and suggest what could be missing?
我使用Apple AirLocate示例代码,将一台设备配置为iBeacon,并执行以下步骤来测试我的代码:
I use the Apple AirLocate sample code to configure one device as iBeacon and perform the following steps to test my code:
步骤:
- 编译并执行设备B上的AirLocate 示例代码
- 在设备B上的A设备上编译并执行此代码
- AirLocate应用程序将设备配置为iBeacon,选择以下UUID: 74278BDA-B644-4520-8F0C-720EAF059935
- compile and execute AirLocate sample code on device B
- compile and execute this code on device A
- in device B use AirLocate app to configure device as iBeacon choosing the following UUID: "74278BDA-B644-4520-8F0C-720EAF059935"
结果:
- 在消息中注明
预期结果:
- 在消息中注明
- 已输入区域
为什么?
se是我的plist条目:
Those are my plist entries:
< img src = https://i.stack.imgur.com/eFoQi.png alt =在此处输入图片描述>
代码:
#import "BeaconMonitoring.h"
@implementation BeaconMonitoring
- (instancetype)init
{
self = [super init];
if (self) {
self.locationManager = [[CLLocationManager alloc] init];
if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
self.locationManager.delegate = self;
self.locationManager.pausesLocationUpdatesAutomatically = NO;
self.monitoredRegions = [[NSMutableArray alloc] initWithCapacity:10];
}
return self;
}
- (void) startRangingForBeacons{
NSLog(@"in startRangingForBeacons");
[self.locationManager startUpdatingLocation];
[self startMonitoringForRegion:[[NSUUID alloc] initWithUUIDString:@"74278BDA-B644-4520-8F0C-720EAF059935"] :@"b"];
}
- (void) startMonitoringForRegion:(NSUUID*)beaconUUID :(NSString*)regionIdentifier{
/**
Alternatively:
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:@"xxxx"
major:10
minor:20
identifier:@"name"]
**/
// Override point for customization after application launch.
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconUUID identifier:regionIdentifier];
beaconRegion.notifyEntryStateOnDisplay = NO;
beaconRegion.notifyOnEntry = YES;
beaconRegion.notifyOnExit = YES;
[self.locationManager startMonitoringForRegion:beaconRegion];
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
[self.monitoredRegions addObject:beaconRegion];
}
- (void) stopRangingForbeacons{
NSLog(@"in stopRangingForbeacons");
[self.locationManager stopUpdatingLocation];
for (int i=0; i < [self.monitoredRegions count]; i++) {
NSObject * object = [self.monitoredRegions objectAtIndex:i];
if ([object isKindOfClass:[CLBeaconRegion class]]) {
CLBeaconRegion * region = (CLBeaconRegion*)object;
[self.locationManager stopMonitoringForRegion:region];
[self.locationManager stopRangingBeaconsInRegion:region];
}
else{
NSLog(@"Serious error, should never happen!");
}
}
}
#pragma CLLocationManagerDelegate
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
[manager startRangingBeaconsInRegion:(CLBeaconRegion*)region];
[self.locationManager startUpdatingLocation];
NSLog(@"You entered the region.");
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
[manager stopRangingBeaconsInRegion:(CLBeaconRegion*)region];
[self.locationManager stopUpdatingLocation];
NSDictionary * notificationData = @{ @"value" : @"exitedRegion"};
[[NSNotificationCenter defaultCenter] postNotificationName:@"dataUpdate" object:nil userInfo:notificationData];
NSLog(@"You exited the region.");
// [self sendLocalNotificationWithMessage:@"You exited the region."];
}
- (void) locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
NSLog(@"did determine state");
switch (state) {
case CLRegionStateInside:
NSLog(@"state inside");
break;
case CLRegionStateOutside:
NSLog(@"state outside");
break;
case CLRegionStateUnknown:
NSLog(@"state unknown");
break;
default:
NSLog(@"Default case: Region unknown");
break;
}
}
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
NSLog(@"Did range %lu beacon in region %@", (unsigned long)[beacons count], region.identifier);
NSString * visibleInformation = [NSString stringWithFormat:@"(%lu)", (unsigned long)[beacons count]];
for (int i=0; i<[beacons count]; i++) {
CLBeacon *beacon = [beacons objectAtIndex:i];
if ([beacons count] == 1) {
NSNumber * distance = [NSNumber numberWithFloat:beacon.accuracy];
visibleInformation = [NSString stringWithFormat:@"%i-%i is %f", beacon.major.intValue, beacon.minor.intValue, distance.doubleValue];
}
else{
visibleInformation = [visibleInformation stringByAppendingString:[NSString stringWithFormat:@" %i-%i ", beacon.major.intValue, beacon.minor.intValue]];
}
}
}
@end
第二部分:
我看过 AirLocate 源代码,以了解是否必须在消息内部的状态中触发某些内容才能使监视正常工作。但是我发现** didDetermineState **方法是在AppDelegate中实现的。
I had a look at the AirLocate source code to understand if there was something that I had to trigger in the state inside message to get the monitoring working properly. However I found that the ** didDetermineState** method is implemented in the AppDelegate.
为什么?
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
/*
A user can transition in or out of a region while the application is not running. When this happens CoreLocation will launch the application momentarily, call this delegate method and we will let the user know via a local notification.
*/
UILocalNotification *notification = [[UILocalNotification alloc] init];
if(state == CLRegionStateInside)
{
notification.alertBody = NSLocalizedString(@"You're inside the region", @"");
}
else if(state == CLRegionStateOutside)
{
notification.alertBody = NSLocalizedString(@"You're outside the region", @"");
}
else
{
return;
}
/*
If the application is in the foreground, it will get a callback to application:didReceiveLocalNotification:.
If it's not, iOS will display the notification to the user.
*/
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
推荐答案
假设:R =制造区域由B并由A收听
Assumption: R = Region made by B and listened to by A
如果A在B之前开始:
- 应用程序A应该告诉您确定区域R的状态=外部
- 应用程序A应该运行didEnter区域R
情况2
如果A实际上是在B之后启动的:
case 2
IF A was infact started after B:
- 仅应运行defineState Region R =内部
结尾。这里没有2,因为它永远不会进入范围。它是从里面开始的
the end. There is no 2 here because it never enters the range. it was started inside of it
这篇关于了解iOS中的iBeacon:didDetermineState和didEnterRegion事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!