2014-09-26 183 views
8

自iOS8更新以来,我遇到了问题,现在我的应用连接到BLE设备,并定期读取RSSI,这要归功于定时器和ReadRSSI方法。ReadRSSI不会调用委托方法

调用readRSSI方法(使用断点检查),直到此时一切正常。

根据文档调用readRSSI应触发回调

- (void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(NSError *)error 

然而,这种委托方法不叫每次。但是,当我关闭和打开手机蓝牙时,我可以恢复RSSI更新。有没有人遇到过这个问题?我怎样才能解决它?

+0

尝试连接到每个[我对类似问题的回答]外设(http://stackoverflow.com/a/27030526/4272525)。 – 2014-11-20 02:12:17

+0

我不得不重置我的iPhone,让它再次工作,按住电源和主屏幕按钮。 – marcelosalloum 2015-10-28 17:56:36

回答

4

我得到了同样的问题,首先想到这可能是我的错,但后来事实证明这很奇怪。

我写了类似的程序,用iPhone连接到BLE信号灯,并用[CBPeripheral readRSSI]获得信号强度。当BLE信标首次连接到我的iPhone时,一切都会顺利进行。但是如果它断开连接并重新连接,readRSSI方法将不会再被调用。 只有在我的iPhone上重新启动蓝牙后,问题才会解决。

我以调试模式运行程序,一步一步,令我惊讶的是,我根本没有发现任何问题。即使我断开连接多次并重新连接,readRSSI仍然可以正确调用。

希望这可能有所帮助。我也在等待这个奇怪的事情的答案。

+0

感谢您的回答,我刚刚填补了一个Apple bug报告,我会保持你的发布 – 2014-09-29 08:09:01

+0

因此,苹果只是关闭了我的错误,因为#18476971的副本,但我无法访问它,所以我没有线索的苹果调查 – 2014-10-03 08:57:47

+0

我认为他们已经意识到这个问题,看来BLE在iOS8中有很多问题。 – 2014-10-05 03:27:17

1

我有8.0,它工作正常。

-(void) startScanForRSSI{ 

    timerRSSI = [NSTimer scheduledTimerWithTimeInterval:10.0f target:self selector:@selector(detectRSSI) userInfo:nil repeats:YES]; 

} 

- (void)detectRSSI { 

    if (state == ...) { 
     peripheral.delegate = self; 
     [peripheral readRSSI]; 
    } else { 
     if (timerRSSI && [timerRSSI isValid]) { 
      [timerRSSI invalidate]; 
     } 
    } 
} 



- (void)peripheralDidUpdateRSSI:(CBPeripheral *)peripheral error:(NSError *)error { 



    NSLog(@"Got RSSI update: %4.1f", [peripheral.RSSI doubleValue]); 


    NSNumber *rssiNum = peripheral.RSSI; 
} 

由于上面在iOS 8中不推荐使用,所以尝试使用另一个代理时,会报告回来。

-(void) peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(NSError *)error { 
    NSLog(@"Got RSSI update in didReadRSSI : %4.1f", [RSSI doubleValue]); 
} 

这似乎是一个OSX委托方法。苹果很可能会在iOS中为RSSI添加一些内容。

在iOS 8.0中,didReadRSSI正在工作。在8.0.2文档中,它不在iOS下列出。

如果我把两种方法didReadRSSI被称为iOS的8 & peripheralDidUpdateRSSI被称为iOS的7

,直到苹果把东西RSSI所以不更新到iOS 8.0.2。

有没有人试过iOS 8.1 beta?

看起来像扫描设备时无法读取RSSI。如果已启动对[CBCentralManager scanForPeripheralsWithServices ...]的调用,则不会发生ReadRSSI的影响(不会调用委托)。但是如果[CBCentralManager stopScan]发出,ReadRSSI开始响应。

另请注意:设备必须处于连接状态才能发出命令,否则您将得到: CoreBluetooth [API错误] CBPeripheral只能在连接状态下接受命令。

2

我最近遇到这个问题,我有多个问题导致它。下面是清单的方式解决方案,从最简单到最复杂的:

  1. CBCentralManager不会抱持着强烈的参考peripheral,你需要自己保持它。
  2. 请确保你确实是peripheral.delegate
  3. 确保您正在实施新方法peripheral(peripheral:didReadRSSI:error:)而不是旧方法。
  4. iOS 8.0.2引入了与上述方法有关的问题,之后的任何版本8.1,8.2,8.3都没有问题(What @ Gamma-Point提到)。
  5. 只能readRSSI为连接到设备上的中央,所以:
    1. 对于被发现找回的设备,你可以做scanForPeripheralsWithServices(_:options:)时通过[CBCentralManagerScanOptionAllowDuplicatesKey : true]。如this answer所示。
    2. 此外,方法central.retrieveConnectedPeripheralsWithServices有一个问题。此方法返回“已连接”设备,但readRSSI和服务发现都不起作用,直到您实际拨打connectPeripheral(_:options:)为止,因此即使它们连接到iPhone/iPad/AppleWatch,它们也没有连接到您的中央,非常烦人。

这最后一个是大抓把柄对我来说,我希望“挑选最接近的”连接或发现的设备,但无法保持更新对他们的RSSI。文档也没有说任何东西。

我最终做的是建立一个所有设备索引为[UUID : Device](设备是CBPeripheral的包装器)的大字典。通过发现添加的设备通过de discover方法更新其RSSI,并通过调用readRSSI的蓝牙队列上的GCD定时器更新其连接的RSSI,并更新其自己的RSSI读数。