2014-09-26 226 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讀數。