10.9 CoreBluetooth RetrivePeriperals


Я разрабатываю приложение на OSX, которое использует CoreBluetooth. Я столкнулся с проблемой на OSX Mavericks, которую я не могу обойти. (Все это прекрасно работает на OSX 10.8).

Сначала пройдем через поток приложения

Введите описание изображения здесь

Этот поток довольно установлен и успешно используется в приложениях iOS и работает на 10.8. Итак, на Mavericks первый запуск завершается успешно. Он сканирует, находит и правильно подключается к устройству. Это также экономит идентификатор UUID устройства .plist файл вместе с другими свойствами.

При повторном запуске приложения он пытается спуститься по левой колонке потока, где, по-видимому, возникают проблемы.

Итак, первая проблема, которую я заметил, заключалась в том, что мой вызов self.central retrievePeripherals: никогда не вызывает обратный вызов делегата -(void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals . Он просто никогда не получает обратный вызов на Mavericks.

Моей следующей мыслью было: "о, у них есть новый API для извлечения периферийных устройств на Mavericks, а старый устарел, давайте попробуем что". Поэтому я добавил в свои звонки NSArray *identifiers = [self.central retrievePeripheralsWithIdentifiers:@[uuid]];, и меня поймали в ловушку ожидания на семпахоре. При более тщательной отладке того, что происходило, оказалось, что иногда мой CBCentralManager попадает в состояние CBCentralManagerStateUnknown и никогда не обновляет состояние до более нового.

Следующее, что я попытался сделать, - это запустить Монитор активности и убить синеватый процесс. Наконец, мой обратный вызов делегата для -(void)centralManagerDidUpdateState:(CBCentralManager *)central был вызван с правильным CBCentralManagerStatePoweredOn, поэтому я снова выполнил retrievePeripheralsWithIdentifiers и получен пустой массив.

Таким образом, все эти проблемы, по-видимому, каким-то образом связаны с blued. Есть ли у кого-нибудь более глубокое понимание этого процесса, чтобы уклониться от того, что происходит?

Мой главный вопрос. Почему это работает в первый раз через приложение, но не во второй? После выхода из приложения после первоначального сканирования и подключения кажется, что я больше не могу использовать систему bluetooth для чего-либо без сброса blued (который даже тогда не извлекает периферийные устройства). Есть ли какая-то разновидность последовательность выключения, которую мне нужно сделать на CBCentralManager, чтобы блюд не ушел в самоволку?

Любой совет будет очень высоко оценен!

1 3

1 ответ:

Хотя это, очевидно, очень старая нить, я наткнулся на тот же вопрос сегодня и решил опубликовать исправление для потомков.

Я пытался взломать простое приложение, основанное на примере HeartRateMonitor, представленном Apple . К сожалению, он не работает на 10.9, если autoConnect установлен в TRUE, что еще хуже, он ставит blued на колени.

В 10.9 вызов (устаревший) retrievePeripherals замораживает blued без возможности восстановления. CBCentralManager переходит в CBCentralManagerStateUnknown, Bluetooth не может быть включен / выключен с помощью функций ОС и т. д. Единственное решение, которое я нашел, - это killall -9 blued.

Тем не менее, синхронные retrievePeripheralsWithIdentifiers хорошо работали для меня (на 10.9.4). Вот соответствующая выдержка из модифицированного кода HeartRateMonitor:
/* Retreive already known devices */
if(autoConnect)
{
    NSArray *peripherals = [manager retrievePeripheralsWithIdentifiers:[NSArray arrayWithObject:(id)aPeripheral.identifier]];

    NSLog(@"Retrieved peripheral: %lu - %@", [peripherals count], peripherals);

    [self stopScan];

    /* If there are any known devices, automatically connect to it.*/
    if([peripherals count] >=1)
    {
        [indicatorButton setHidden:FALSE];
        [progressIndicator setHidden:FALSE];
        [progressIndicator startAnimation:self];
        peripheral = [peripherals objectAtIndex:0];
        [peripheral retain];
        [connectButton setTitle:@"Cancel"];
        [manager connectPeripheral:peripheral options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
    }
}