5

我制作了一个注册信标区域并开始使用 CLLocationManager 监控这些区域的应用程序

CLLocationManager *manager = [[CLLocationManager alloc] init];
manager.delegate = self;

CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:estimoteUUID major:12445 identifier:@"id"];
region.notifyEntryStateOnDisplay = YES;
region.notifyOnEntry = YES;
[manager startMonitoringForRegion:region];

当我从信标走得足够远并回到范围内时,这很有效。但是,如果我已经在信标区域的范围内启动应用程序,我也希望didEnterRegion触发委托方法,而不仅仅是当我回到边界时。有没有简单的方法来实现这一目标?或者让 CLLocationManager 认为我们已经离开信标范围的方法?

另一篇文章说设置region.notifyEntryStateOnDisplay = YES;并按下保持按钮可以做到这一点 - 但我没有得到这个工作(iOS 7.1,iPhone 5S)。

4

3 回答 3

3

从苹果的文档中:

注册授权应用程序后立即开始对地理区域的监控。但是,不要期望立即收到事件,因为只有越界才会产生事件。特别是,如果用户的位置在注册时已经在区域内,则位置管理器不会自动生成事件。相反,您的应用程序必须等待用户跨越区域边界,然后才能生成事件并将其发送给委托。要检查用户是否已经在区域边界内,请使用 CLLocationManager 类的 requestStateForRegion: 方法。

所以我最终这样做了:

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic, strong) NSDictionary *regionDictionary;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // setup regions in case you have multiple regions
    self.regionDictionary = @{@"com.test" : @"2FAE2A83-1634-443B-8A0C-56704F81A181"};

    // setup location manager
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;

    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
        [self.locationManager requestAlwaysAuthorization];
    }

    [self.locationManager startUpdatingLocation];

    //start monitoring for all regions
    for (NSString *key in self.regionDictionary.allKeys) {
        CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:self.regionDictionary[key]] identifier:key];
        [self.locationManager startMonitoringForRegion:beaconRegion];
    }
}

- (void)locationManager:(CLLocationManager*)manager didEnterRegion:(CLRegion *)region {
    if (region.identifier.length != 0) {
        CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:self.regionDictionary[region.identifier]] identifier:region.identifier];
        [self.locationManager startRangingBeaconsInRegion:beaconRegion];
    }
}

- (void)locationManager:(CLLocationManager*)manager didExitRegion:(CLRegion *)region {
    if (region.identifier.length != 0) {
        CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:self.regionDictionary[region.identifier]] identifier:region.identifier];
        [self.locationManager stopRangingBeaconsInRegion:beaconRegion];
    }
}

- (void)locationManager:(CLLocationManager*)manager didRangeBeacons:(NSArray*)beacons inRegion:(CLBeaconRegion*)region {
    // Beacon found!
    CLBeacon *foundBeacon = [beacons firstObject];
    NSLog(@"UUID:%@; major:%@; minor:%@;", foundBeacon.proximityUUID.UUIDString, foundBeacon.major, foundBeacon.minor);
 }

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
    if ([region isKindOfClass:[CLBeaconRegion class]] && state == CLRegionStateInside) {
        [self locationManager:manager didEnterRegion:region];
    }
}

- (void)locationManager:(CLLocationManager *) manager didStartMonitoringForRegion:(CLRegion *) region {
    [manager requestStateForRegion:region];
}
于 2015-01-22T16:05:02.807 回答
0

根据用户当前位置计算仪表值,其中信标的起点和终点应该在信标完整无线电内,然后强制调用 didEnterRegion 或执行您想做的任何操作。

于 2014-06-10T05:58:22.380 回答
0

startMonitoringForeRegion:尝试在:之后插入这一行[self.locationManager requestStateForRegion:region];

于 2014-06-10T06:01:37.397 回答