Ios 信标监控 didEnterRegion 事件仅触发 "on the ipad" 即使我将 desiredAccuracy 和 distanceFilter 字段设置为 100 米
Ios beacon monitoring didEnterRegion event fires only "on the ipad" even if i set desiredAccuracy and distanceFilter fields to 100 meters
在下面的代码中,我将字段 desiredAccuracy 和 distanceFilter 设置为 100。但它不能正常工作。正如我在标题中提到的,当我将信标放在 ipad 上时,didEnterRegion 会触发,当我收回时,大约 15 秒后,didExitRegion 会触发。我错过了什么吗?
#import "AppDelegate.h"
#import <CoreLocation/CoreLocation.h>
#import <CoreBluetooth/CoreBluetooth.h>
@interface AppDelegate() <CLLocationManagerDelegate>
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (assign, nonatomic) BOOL dropEmptyRanges;
@end
@implementation AppDelegate
- (instancetype)init
{
if (self = [super init]) {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.pausesLocationUpdatesAutomatically = NO;
self.locationManager.distanceFilter = 100;
self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
}
return self;
}
-(CLBeaconRegion *) createBeaconRegion: (NSString *) identifier
uuid: (NSString *) uuid
major: (NSInteger) major
minor:(NSInteger) minor
{
NSUUID *beaconUUID = [[NSUUID alloc] initWithUUIDString:uuid];
unsigned short mj = (unsigned short) major;
unsigned short mi = (unsigned short) minor;
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconUUID major:mj
minor:mi
identifier:identifier];
NSLog(@"createBeaconRegion with: identifier - uuid - major - minor");
beaconRegion.notifyOnEntry = YES;
beaconRegion.notifyOnExit = YES;
beaconRegion.notifyEntryStateOnDisplay = YES;
return beaconRegion;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
CLBeaconRegion *beaconRegion = [self createBeaconRegion:@"backgroundRegion" uuid:@"fda50693-a4e2-4fb1-afcf-c6eb07647825" major:10004 minor:5178];
[self.locationManager startMonitoringForRegion:beaconRegion];
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
[self.locationManager startUpdatingLocation];
if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeSound|UIUserNotificationTypeBadge categories:nil]];
}
return YES;
}
-(void)locationManager:(CLLocationManager *)manager
didEnterRegion:(CLBeaconRegion *)region {
NSLog(@"Beacon did enter region");
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:3];
localNotification.alertBody = @"Beacon did enter region";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
-(void)locationManager:(CLLocationManager *)manager
didExitRegion:(CLBeaconRegion *)region {
NSLog(@"Beacon did exit region");
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:3];
localNotification.alertBody = @"Beacon did exit region";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
-(void)locationManager:(CLLocationManager*)manager
didRangeBeacons: (NSArray *) beacons
inRegion:(CLBeaconRegion *)region{
NSLog(@"Beacon did range");
}
@end
您目前没有测距任何信标。尝试添加以下行:
-(void)locationManager:(CLLocationManager *)manager
didEnterRegion:(CLBeaconRegion *)region {
NSLog(@"Beacon did enter region");
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:3];
localNotification.alertBody = @"Beacon did enter region";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[manager startRangingBeaconsInRegion:region];
}
-(void)locationManager:(CLLocationManager *)manager
didExitRegion:(CLBeaconRegion *)region {
NSLog(@"Beacon did exit region");
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:3];
localNotification.alertBody = @"Beacon did exit region";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[manager stopRangingBeaconsInRegion:region];
}
遗憾的是,此技术不适用于限制信标检测。
字段 locationManager.distanceFilter
和 locationManager.desiredAccuracy
不适用于信标检测。当根据 GPS/Cell/WiFi 定位获取位置更新时,这些仅对来自 CoreLocation 的回调有任何影响。文档 here 说了这么多:
This property is used only in conjunction with the standard location services and is not used when monitoring significant location changes.
虽然该声明听起来有点含糊,但 "standard location services" 的意思是当您调用 startUpdatingLocation
以获取这些非信标位置更新时。您可以阅读有关此内容的更多信息 here。上面的引文虽然没有明说,但是如果也说"This property is used only in conjunction with the standard location services and is not used when monitoring significant location changes or monitoring beacon regions."
就更清楚了
如果您想根据距离限制信标检测,则无法使用监控 API 来实现。您必须对信标进行测距,每隔一秒获得一次距离估计,并且仅在您发现估计距离小于所需阈值时才触发事件。
在下面的代码中,我将字段 desiredAccuracy 和 distanceFilter 设置为 100。但它不能正常工作。正如我在标题中提到的,当我将信标放在 ipad 上时,didEnterRegion 会触发,当我收回时,大约 15 秒后,didExitRegion 会触发。我错过了什么吗?
#import "AppDelegate.h"
#import <CoreLocation/CoreLocation.h>
#import <CoreBluetooth/CoreBluetooth.h>
@interface AppDelegate() <CLLocationManagerDelegate>
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (assign, nonatomic) BOOL dropEmptyRanges;
@end
@implementation AppDelegate
- (instancetype)init
{
if (self = [super init]) {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.pausesLocationUpdatesAutomatically = NO;
self.locationManager.distanceFilter = 100;
self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
}
return self;
}
-(CLBeaconRegion *) createBeaconRegion: (NSString *) identifier
uuid: (NSString *) uuid
major: (NSInteger) major
minor:(NSInteger) minor
{
NSUUID *beaconUUID = [[NSUUID alloc] initWithUUIDString:uuid];
unsigned short mj = (unsigned short) major;
unsigned short mi = (unsigned short) minor;
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconUUID major:mj
minor:mi
identifier:identifier];
NSLog(@"createBeaconRegion with: identifier - uuid - major - minor");
beaconRegion.notifyOnEntry = YES;
beaconRegion.notifyOnExit = YES;
beaconRegion.notifyEntryStateOnDisplay = YES;
return beaconRegion;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
CLBeaconRegion *beaconRegion = [self createBeaconRegion:@"backgroundRegion" uuid:@"fda50693-a4e2-4fb1-afcf-c6eb07647825" major:10004 minor:5178];
[self.locationManager startMonitoringForRegion:beaconRegion];
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
[self.locationManager startUpdatingLocation];
if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeSound|UIUserNotificationTypeBadge categories:nil]];
}
return YES;
}
-(void)locationManager:(CLLocationManager *)manager
didEnterRegion:(CLBeaconRegion *)region {
NSLog(@"Beacon did enter region");
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:3];
localNotification.alertBody = @"Beacon did enter region";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
-(void)locationManager:(CLLocationManager *)manager
didExitRegion:(CLBeaconRegion *)region {
NSLog(@"Beacon did exit region");
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:3];
localNotification.alertBody = @"Beacon did exit region";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
-(void)locationManager:(CLLocationManager*)manager
didRangeBeacons: (NSArray *) beacons
inRegion:(CLBeaconRegion *)region{
NSLog(@"Beacon did range");
}
@end
您目前没有测距任何信标。尝试添加以下行:
-(void)locationManager:(CLLocationManager *)manager
didEnterRegion:(CLBeaconRegion *)region {
NSLog(@"Beacon did enter region");
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:3];
localNotification.alertBody = @"Beacon did enter region";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[manager startRangingBeaconsInRegion:region];
}
-(void)locationManager:(CLLocationManager *)manager
didExitRegion:(CLBeaconRegion *)region {
NSLog(@"Beacon did exit region");
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:3];
localNotification.alertBody = @"Beacon did exit region";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[manager stopRangingBeaconsInRegion:region];
}
遗憾的是,此技术不适用于限制信标检测。
字段 locationManager.distanceFilter
和 locationManager.desiredAccuracy
不适用于信标检测。当根据 GPS/Cell/WiFi 定位获取位置更新时,这些仅对来自 CoreLocation 的回调有任何影响。文档 here 说了这么多:
This property is used only in conjunction with the standard location services and is not used when monitoring significant location changes.
虽然该声明听起来有点含糊,但 "standard location services" 的意思是当您调用 startUpdatingLocation
以获取这些非信标位置更新时。您可以阅读有关此内容的更多信息 here。上面的引文虽然没有明说,但是如果也说"This property is used only in conjunction with the standard location services and is not used when monitoring significant location changes or monitoring beacon regions."
如果您想根据距离限制信标检测,则无法使用监控 API 来实现。您必须对信标进行测距,每隔一秒获得一次距离估计,并且仅在您发现估计距离小于所需阈值时才触发事件。