2015-04-04 2 views
0
_manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; 
[NSThread sleepForTimeInterval:10]; // waiting for centralManagerDidUpdateState invocation 
[_manager scanForPeripheralsWithServices:@[ _serviceUUID ] options:nil]; // warning here 

... 

- (void)centralManagerDidUpdateState:(CBCentralManager *)central { 
    NSLog(@"CBCentralManager state is %i", (int)central.state); 
} 

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI { 
    NSLog(@"Found peripheral: %@", peripheral); 
    ... 
} 

По некоторым причинам делегат centralManagerDidUpdateState никогда не вызывается, и я получаю предупреждение:CBCentralManager не включен

2015-04-04 12: 59: 20,850 xctest [30276: 303] CoreBluetooth [ ПРЕДУПРЕЖДЕНИЕ] не включен

при открытии для периферийных устройств. AFAIK он должен работать на OSX (я на MBA 2013 и OSX Maverics и работает XCTest). Bluetooth включен, и я могу запустить приложение LightBlue и обнаружить некоторые устройства BLE (я уверен, что ни одно приложение BLE не работает при тестировании моего кода). Таким образом, no didDiscoverPeripheral вызывается, как ожидалось.

+0

возможно дубликат [не может подключиться устройство Bluetooth в ИОС 8 даже существующий код не найти Bluetooth и главное это woring очень хорошо КСН 7] (http://stackoverflow.com/questions/26074216/ Невозможно подключиться-bluetooth-устройство-в-ios-8-even-existing-code-not-find-bluet) – Paulw11

+0

Тестирование базового bluetooth сложно. Вы должны тщательно его спланировать. Но я бы сказал, что вам будет намного лучше тестировать части CB вручную, потому что есть слишком много факторов ошибки, которые делают автоматическое тестирование ненадежным. Вы должны отделить взаимодействия CB в небольшом модуле/библиотеке/интерфейсе, а модуль тестирует только взаимодействия с этим интерфейсом, где вы можете легко заменить любые возвращаемые значения и обратные вызовы для любого вызова. – allprog

ответ

0

Я пытался использовать фоновый поток, как sleepForTimeInterval блокирует основной поток и CBCentralManager использует основной поток по умолчанию:

dispatch_queue_t bt_queue = dispatch_queue_create("BT_queue", 0); 
_manager = [[CBCentralManager alloc] initWithDelegate:self queue:bt_queue]; 

Так centralManagerDidUpdateState: вызывается почти сразу и периферийная обнаружен с didDiscoverPeripheral:.

+0

Хорошо использовать отдельную очередь для Core Bluetooth, но не 'sleep'. Core Bluetooth более или менее построен исключительно из асинхронных вызовов и обратных вызовов. Положитесь на обратные вызовы и не пытайтесь сами что-то делать. Прочтите соответствующие разделы [Руководства по Apple CB] (https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/AboutCoreBluetooth/Introduction.html) – allprog

+0

Хорошо иметь подтверждение, что использование отдельной очереди решение (в отличие от Palw11 настаивало). Я использовал 'sleep', чтобы иметь логику приложения в одном месте (вместо лота callback) только для теста. В общем случае я согласен, что спать не очень хорошо. – 4ntoine

0

С OS X 10.13.2 аргумент очереди для CBCentralManager.init() должен быть не ноль, чтобы вызвать обратный вызов, например. в Swift

manager = CBCentralManager(
    delegate: self, 
    queue: DispatchQueue(label: "BT_queue")) 
Смежные вопросы