接近 API 的不一致行为 - iOS iBeacon

Posted

技术标签:

【中文标题】接近 API 的不一致行为 - iOS iBeacon【英文标题】:Inconsistent behaviour by proximity API - iOS iBeacon 【发布时间】:2017-01-09 08:11:17 【问题描述】:

我正在将 ios 设备转换为 iBeacon,然后使用核心位置的测距 API 来检测信标的接近度。现在,这可行,但我看到了一种不可预测的行为,有时在定义的距离(比如 10 米外)我看到没有信标,有时看到远信标,有时看到近信标。

有没有办法让这种行为更加一致?

- (void)viewDidLoad 
    [super viewDidLoad];

    self.beaconSwitch.on = NO;
    self.beaconView.backgroundColor = [UIColor clearColor];
    self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
    BeaconRegion *beaconRegion = [[BeaconRegion alloc] init];
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconRegion.uuid major:[beaconRegion.major shortValue] minor:[beaconRegion.minor shortValue] identifier:beaconIdentifier];



- (void)viewWillDisappear:(BOOL)animated 
    [super viewWillDisappear:animated];
    [self.peripheralManager stopAdvertising];



- (IBAction)doneButtonPressed:(id)sender 
    [self dismissViewControllerAnimated:YES completion:nil];


- (IBAction)beaconSwitchPressed:(id)sender 
    if (self.beaconSwitch.on == true) 
        self.beaconView.beaconState = BNBeaconStateBroadcasting;

        NSDictionary *data = [self.beaconRegion peripheralDataWithMeasuredPower:nil];
        [self.peripheralManager startAdvertising:data];
     else 
        self.beaconView.beaconState = BNBeaconStateStop;
        [self.peripheralManager stopAdvertising];
    

以下是我将 iOS 设备转换为信标的方法:

这就是我如何接近它:

- (void)viewDidLoad 
    [super viewDidLoad];

    BeaconRegion *beaconRegion = [[BeaconRegion alloc] init];
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconRegion.uuid identifier:beaconIdentifier];
    self.beaconRegion.notifyOnEntry = YES;
    self.beaconRegion.notifyOnExit = YES;
    self.beaconRegion.notifyEntryStateOnDisplay = YES;
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    self.detectionSwitch.on = NO;


- (IBAction)beaconDetectionSwitchPressed:(id)sender 
    if (self.detectionSwitch.isOn) 
        [self.locationManager startMonitoringForRegion:self.beaconRegion];
        [self.locationManager requestStateForRegion:self.beaconRegion];
     else 
        self.lastProximity = CLProximityUnknown;
        [self.locationManager stopMonitoringForRegion:self.beaconRegion];
        [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
        self.titleLabel.text = @"";
        self.messageLabel.text = @"";
    


- (void)viewWillDisappear:(BOOL)animated 
    [super viewWillDisappear:animated];
    [self.locationManager stopMonitoringForRegion:self.beaconRegion];
    [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
    self.locationManager = nil;


- (void)locationManager:(CLLocationManager *)iManager didEnterRegion:(CLRegion *)iRegion 
    NSLog(@"Detected a beacon");

    if (![self.beaconRegion isEqual:iRegion]) 
        return;
    

    NSLog(@"Entered into the beacon region = %@", iRegion);

    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];


- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region 
    NSLog(@"Ranging beacon successful");

    if (beacons.count > 0) 
        CLBeacon *nearestBeacon = beacons[0];
        CLProximity currentProximity = nearestBeacon.proximity;

        if (currentProximity == self.lastProximity) 
            NSLog(@"No Change in Beacon distance");
         else 
            self.lastProximity = currentProximity;
            [self updateUserAboutProximity];
        
     else 
        self.lastProximity = CLProximityUnknown;
    



- (void)updateUserAboutProximity 
    NSString *title = @"--";
    NSString *message = @"--";
    switch (self.lastProximity) 
        case CLProximityUnknown:
            title = @"No Beacon";
            message = @"There is no nearby beacon";
        
            break;

        case CLProximityImmediate:
            title = @"Immediate Beacon";
            message = @"You are standing immediate to video wall!";
        
            break;

        case CLProximityNear:
            if (self.isServerCallOn) 
                title = @"Near Beacon";
                message = @"You are standing near to video wall!";
             else 
                title = @"Near Beacon";
                message = @"You are standing near to video wall! Initiating a server call.";

                if (!self.ignoreSeverCallTrigger) 
                    self.isServerCallOn = YES;
                    [self talkToServer];
                 else 
                    NSLog(@"Ignoring server call trigger");
                    message = @"Ignoring server call trigger!";
                
            
        
            break;

        case CLProximityFar:
            title = @"Far Beacon";
            message = @"You are standing far from video wall!";
        
            break;
        default:
            break;
    
    self.titleLabel.text = title;
    self.messageLabel.text = message;


- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region 
    if (state == CLRegionStateInside) 
        NSLog(@"Starting Ranging");
        [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
    


- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status 
    if (![CLLocationManager locationServicesEnabled]) 
        NSLog(@"Location Service Not Enabled");
    

    if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorizedAlways) 
        NSLog(@"Location Service Not Authorized");
    

【问题讨论】:

【参考方案1】:

目前,我对接收信号强度指示器 (rssi) 值设置了一个条件,并在附近接受 > -60 的任何内容,以使距离更可预测。因此,如果 rssi > -60,我也会在 Nearby 附近触发我的操作。

【讨论】:

以上是关于接近 API 的不一致行为 - iOS iBeacon的主要内容,如果未能解决你的问题,请参考以下文章

C++ std::vector 乘法中是不是存在已知的不一致行为?

SpringMVC:取决于 url 扩展的不一致映射行为

iOS7 中 jQuery Mobile 滑动事件的不稳定行为

YouTube iFrame API 行为不一致/不确定

Spring boot:REST API 行为不一致后版本升级

如何解释 visualvm cpu 示例和从中创建的快照之间的不一致?