简体   繁体   English

ReadRSSI不会调用委托方法

[英]ReadRSSI doesn't call the delegate method

I got a problem since the iOS 8 update, right now my app is connected to a BLE device and periodically reads the RSSI thanks to a timer and the ReadRSSI method. 自从iOS 8更新后我遇到了问题,现在我的应用程序连接到BLE设备,并且由于定时器和ReadRSSI方法而定期读取RSSI。

The readRSSI method is called (checked with a breakpoint) so until this point everything is fine. 调用readRSSI方法(使用断点检查),所以在此之前一切都很好。

According to the documentation calling the readRSSI should trigger the callback 根据调用readRSSI的文档应该触发回调

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

However, this delegate method is not called every time. 但是,每次都不调用此委托方法。 But when I toggle the phone bluetooth off and on, I get back the RSSI updates. 但是,当我关闭和打开手机蓝牙时,我恢复了RSSI更新。 Has anyone already encountered this problem? 有没有人遇到过这个问题? How can i manage to fix it? 我该如何设法修复它?

I got the same problem, first thought it might be my fault, but later it turns out to be really weird. 我遇到了同样的问题,首先想到这可能是我的错,但后来事实证明这很奇怪。

I wrote similar program, using iPhone to connect to a BLE beacon, and use [CBPeripheral readRSSI] to get the signal strength. 我编写了类似的程序,使用iPhone连接到BLE信标,并使用[CBPeripheral readRSSI]来获取信号强度。 Everything goes smooth when the BLE beacon is connected to my iPhone for the first time. 当BLE信标第一次连接到我的iPhone时,一切顺利。 But if it got disconnected, and reconnect again, the method readRSSI won't get called any more. 但如果它断开连接并再次重新连接,则不会再调用readRSSI方法。 Only after I restart the bluetooth on my iPhone, the issue will be resolved. 只有在我重新启动iPhone上的蓝牙后,问题才会得到解决。

I run the program in debug mode, step by step, to my surprise, I found no problem at all. 我一步一步地在调试模式下运行程序,令我惊讶的是,我发现没有任何问题。 Even I disconnect for so many times and reconnect again, the method readRSSI can still be called properly. 即使我多次断开连接并再次重新连接,仍然可以正确调用readRSSI方法。

Hope this may help. 希望这可能有所帮助。 I am also waiting for an answer for this strange thing. 我也在等待这个奇怪的事情的答案。

I recently ran into this issue and I had multiple issues that was causing it. 我最近遇到了这个问题,我遇到了多个问题。 Here's the solutions in checklist fashion, from simplest to most complex: 这是清单方式的解决方案,从最简单到最复杂:

  1. The CBCentralManager won't hold a strong reference to the peripheral , you need to keep it yourself. CBCentralManager不会对peripheral有强烈的引用,您需要自己保留它。
  2. Make sure you actually are the peripheral.delegate . 确保你实际上是peripheral.delegate
  3. Make sure you're implementing the new method peripheral(peripheral:didReadRSSI:error:) and not the old one. 确保您正在实现新方法peripheral(peripheral:didReadRSSI:error:)而不是旧方法。
  4. iOS 8.0.2 introduced issues with the above method, any version after that 8.1, 8.2, 8.3, works without problems (What @Gamma-Point was mentioning). iOS 8.0.2引入了上述方法的问题,8.1,8.2,8.3之后的任何版本都没有问题(什么是@Gamma-Point提到)。
  5. You can only readRSSI for devices that are connected to your central, so: 您只能为连接到中心的设备readRSSI ,因此:
    1. For devices that retrieved by discovery, you can pass [CBCentralManagerScanOptionAllowDuplicatesKey : true] when doing scanForPeripheralsWithServices(_:options:) . 对于通过发现检索的设备,您可以在执行scanForPeripheralsWithServices(_:options:)时传递[CBCentralManagerScanOptionAllowDuplicatesKey : true] As seen in this answer . 正如这个答案所见。
    2. Also, there's a gotcha with the method central.retrieveConnectedPeripheralsWithServices . 此外,还有一个方法是使用central.retrieveConnectedPeripheralsWithServices方法。 this method returns "connected" devices, but the readRSSI nor service discovery work until you actually call connectPeripheral(_:options:) on them, so even though they are connected to the iPhone/iPad/AppleWatch, they are not connected to your central, very annoying. 这个方法返回“连接”设备,但readRSSI和服务发现工作,直到你实际上调用connectPeripheral(_:options:) ,所以即使它们连接到iPhone / iPad / AppleWatch,它们也没有连接到你的中心, 很烦人。

This last one was the big gotcha for me, I was hoping to "pick the closest" connected or discovered device, but couldn't keep the RSSI updated on them. 最后一个对我来说是个大问题,我希望“选择最接近的”连接或发现设备,但无法保持RSSI更新。 Documentation doesn't say anything either. 文档也没有说什么。

What I ended up doing, was to build a big dictionary with all the devices indexed by [UUID : Device] (device being a wrapper for the CBPeripheral ). 我最终做的是建立一个大字典,其中所有设备都被[UUID : Device]索引(设备是CBPeripheral的包装器)。 Devices added via discovery get their RSSI updated via de discover method, and the connected ones via a GCD timer on the bluetooth queue that calls readRSSI and update their own RSSI reading. 通过发现添加的设备通过de discover方法更新其RSSI,并通过蓝牙队列上的GCD计时器更新连接的RSSI,该计时器调用readRSSI并更新其自己的RSSI读数。

I have 8.0, it's working fine. 我有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;
}

Since above is deprecated in iOS 8, trying the other delegate, will report back. 由于上述内容在iOS 8中已弃用,因此尝试其他代理会报告回来。

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

This seems to be an OSX delegate method. 这似乎是一个OSX委托方法。 Apple will probably add something soon in iOS for RSSI. 苹果很可能会在iOS上为RSSI添加一些东西。

In iOS 8.0 didReadRSSI is working. 在iOS 8.0中,didReadRSSI正在运行。 In 8.0.2 documentation it is not listed under iOS. 在8.0.2文档中,它未列在iOS下。

If I put both methods didReadRSSI gets called in iOS 8 & peripheralDidUpdateRSSI gets called in iOS 7. 如果我把两个方法都放在iOS 8中调用didReadRSSI并且在iOS 7中调用peripheralDidUpdateRSSI。

So don't update to iOS 8.0.2 until Apples puts something for RSSI. 所以在Apples为RSSI提供东西之前不要更新到iOS 8.0.2。

Did anyone try iOS 8.1 beta? 有人试过iOS 8.1 beta吗?

Looks like when scanning for devices the RSSI can't be read. 在扫描设备时看起来无法读取RSSI。 If the call to [CBCentralManager scanForPeripheralsWithServices...] has been initiated no effect of ReadRSSI occurs (no delegates are called). 如果已启动对[CBCentralManager scanForPeripheralsWithServices ...]的调用,则不会发生ReadRSSI的影响(不会调用任何代理)。 But if the [CBCentralManager stopScan] is issued the ReadRSSI starts responding. 但是如果发出[CBCentralManager stopScan],则ReadRSSI开始响应。

Also note: the device has to be in connected state to issue commands otherwise you will get: CoreBluetooth[API MISUSE] CBPeripheral can only accept commands while in the connected state. 另请注意:设备必须处于连接状态才能发出命令,否则您将获得:CoreBluetooth [API MISUSE] CBPeripheral只能在连接状态下接受命令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM