未调用 didEnterRegion 和 startRangingForBeacons

Posted

技术标签:

【中文标题】未调用 didEnterRegion 和 startRangingForBeacons【英文标题】:didEnterRegion and startRangingForBeacons not being called 【发布时间】:2015-01-15 15:40:35 【问题描述】:

我一直无法弄清楚为什么 startRangingBeaconsInRegion 从未被调用过。我确定调用了 startMonitoringForRegion,我尝试将 mRegionsArray 输出为字符串并且它有效。但是 didEnterRegion 并没有被调用。我试着来回走动,试图从我的信标中获取信号(即进入该区域),但没有运气。我无法解决可能出现的问题,在这里遇到了很多问题,但没有一个反映了我的问题。

我有一个信标表视图,每个单元格都应该包含每个信标上的信息(主要、次要)。除了,这些单元格没有被填充,因为测距没有发生。 :( 我什至试图改变它,让它只检测一个信标。我知道问题不在于我创建的 Beacon 类,因为 loadTestData() 函数有效......

如果有人能提供帮助,将不胜感激。

BeaconTableViewController.h

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@interface BeaconTableViewController : UITableViewController <CLLocationManagerDelegate>

@property (strong, nonatomic) CLBeaconRegion *beaconRegion;
@property (strong, nonatomic) CLLocationManager *locationManager;

@end

BeaconTableViewController.m

#import "BeaconTableViewController.h"
#import "Beacon.h"
#import "BeaconTableViewCell.h"

@interface BeaconTableViewController () <UITableViewDataSource, UITableViewDelegate>

@property (weak, nonatomic) IBOutlet UITableView *beaconsTableView;
@property (strong, nonatomic) NSMutableArray *beacons;

@end

@implementation BeaconTableViewController

- (void)loadTestData 
    self.beacons = [[NSMutableArray alloc] init];

    Beacon *beacon1 = [[Beacon alloc] init];
    beacon1.major = [[NSNumber alloc] initWithInt:21311];
    beacon1.minor = [[NSNumber alloc] initWithInt:21331];
    [self.beacons addObject:beacon1];
    Beacon *beacon2 = [[Beacon alloc] init];
    beacon2.major = [[NSNumber alloc] initWithInt:10011];
    beacon2.minor = [[NSNumber alloc] initWithInt:10012];
    [self.beacons addObject:beacon2];
    Beacon *beacon3 = [[Beacon alloc] init];
    beacon3.major = [[NSNumber alloc] initWithInt:65535];
    beacon3.minor = [[NSNumber alloc] initWithInt:30136];
    [self.beacons addObject:beacon3];

    [self.beaconsTableView beginUpdates];
    NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:self.beacons.count-1 inSection:0];
    [self.beaconsTableView insertRowsAtIndexPaths:@[newIndexPath]
                                 withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.beaconsTableView endUpdates];


- (void)initRegion 
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"E2C56DB5-DFFB-48D2-B060-D0F5A71096E0"];
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"AB Region"];

    [self.locationManager startMonitoringForRegion:self.beaconRegion];


- (void) locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region 
    UIAlertView *alertMonitoring = [[UIAlertView alloc] initWithTitle:@"User Notification"
                                                    message:@"Started monitoring for region."
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alertMonitoring show];

    NSSet *mRegions = [self.locationManager monitoredRegions];
    NSArray *mRegionsArray = [mRegions allObjects];
    NSString *str = [mRegionsArray componentsJoinedByString:@","];

    UIAlertView *alertRegion = [[UIAlertView alloc] initWithTitle:@"User Notification"
                                                    message:str
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alertRegion show];


- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region 


    UIAlertView *alertRanging = [[UIAlertView alloc] initWithTitle:@"User Notification"
                                                    message:@"Started ranging."
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alertRanging show];

    CLBeacon *foundBeacon = [beacons firstObject];
    Beacon *beacon;
    beacon.major = foundBeacon.major;
    beacon.minor = foundBeacon.minor;

    UIAlertView *alertBeaconFound = [[UIAlertView alloc] initWithTitle:@"User Notification"
                                                    message:[[[@"Major: " stringByAppendingString:[NSString stringWithFormat:@"%@", beacon.major]] stringByAppendingString:@", Minor: "] stringByAppendingString:[NSString stringWithFormat:@"%@", beacon.minor]]
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alertBeaconFound show];
    [self.beacons addObject:beacon];
    [self.beaconsTableView beginUpdates];
    NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:self.beacons.count-1 inSection:1];
    [self.beaconsTableView insertRowsAtIndexPaths:@[newIndexPath]
                                 withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.beaconsTableView endUpdates];



- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"User Notification"
                                                    message:@"Did enter region."
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alert show];
    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];


- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region 
    [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];


- (void)viewDidLoad 
    [super viewDidLoad];
//    [self loadTestData];

    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    [self initRegion];



- (void)didReceiveMemoryWarning 
    [super didReceiveMemoryWarning];


#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    return 1;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    return [self.beacons count];



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

    BeaconTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BeaconCell" forIndexPath:indexPath];
    Beacon *beacon = [self.beacons objectAtIndex:indexPath.row];
    cell.beacon = beacon;

    return cell;

【问题讨论】:

【参考方案1】:

ios 8 下,Apple 对使用位置管理器增加了一些新要求(而 iBeacons 是位置管理器功能)

您必须将密钥 NSLocationAlwaysUsageDescription 和/或 NSLocationWhenInUseUsageDescription 添加到您的 info.plist 文件中,然后在尝试开始监控信标之前,您必须检查授权状态,如果它是 kCLAuthorizationStatusNotDetermined,则必须进行一个新电话,requestAlwaysAuthorizationrequestWhenInUseAuthorization

代码可能如下所示:

  CLAuthorizationStatus status =[CLLocationManager authorizationStatus];
  if (status ==kCLAuthorizationStatusDenied)
  
    NSLog(@"Location manager denied");
  
  theLocManager = [[CLLocationManager alloc] init];
  theLocManager.delegate = self;
  if (status == kCLAuthorizationStatusNotDetermined
      && [theLocManager respondsToSelector: @selector(requestAlwaysAuthorization)])
    [theLocManager requestAlwaysAuthorization];

(您必须添加检查以确保位置管理响应 requestAlwaysAuthorizationrequestWhenInUseAuthorization 方法,因为它们仅适用于 iOS >= 8。)

我不喜欢此操作系统更改的一点是,如果您不发出请求调用,则开始监视信标的调用会静默失败。

【讨论】:

我绝对同意,当开发人员忘记输入此代码时,iOS 8 无法检测信标是一个真正的问题。我希望他们把这个原因作为一个例外。 @davidgyoung,你提交错误报告了吗?我们都应该。

以上是关于未调用 didEnterRegion 和 startRangingForBeacons的主要内容,如果未能解决你的问题,请参考以下文章

AltBeacon:当 BeaconConsumer 从 DidEnterRegion BootstrapNotifier 回调绑定时,未调用 onBeaconServiceConnect

CoreLocation startMonitoringRegion 未触发 didenterregion /didexitregion 代表

didEnterRegion 和 didDetermineState 都调用了

仅在调用 requestAlwaysAuthorization 时才调用 DidEnterRegion。信标

didEnterRegion 以更大的半径调用(iOS)

iBeacon:didEnterRegion 永远不会被调用