CoreBluetooth: обнаружение устройства вне диапазона/тайм-аут подключения

Я разрабатываю инфраструктуру iOS для обработки нескольких устройств BLE (все одинаковые). На данный момент все работает очень хорошо, кроме одного:

Клиент хочет список с доступными устройствами. Но как я могу обнаружить, когда устройство, которое было обнаружено в прошлом, больше не доступно?

Другая проблема возникает, когда я пытаюсь подключиться к устройству, которое больше не доступно. Документация гласит: попытки подключения никогда не выходят за пределы времени и

И да, я никогда не получаю ошибку через didFailToConnectPeripheral.

Я провел некоторое исследование, но не смог понять, как правильно справляться с этими проблемами через CoreBluetooth. Поэтому я разработал свои собственные решения, но я не уверен, что это правильный путь (или, по крайней мере, хороший способ, потому что может быть несколько способов сделать это).

1. Обнаружение устройств, которые больше не доступны

Я сканирую

[_centralManager scanForPeripheralsWithServices:services options:@{CBCentralManagerScanOptionAllowDuplicatesKey: @(TRUE)}];

поэтому я получаю рекламу все время, пока устройство не подключено. Я проверяю таймером, что реклама повторно задерживается в заданный интервал времени (достаточно большой, соответствующий интервалу объявления устройств). Если реклама не произошла в интервале, я удаляю устройство из списка.

2. Обнаружение таймаута подключения Ну, это довольно легкий, я думаю. Я использую свою собственную функцию тайм-аута и отменяю запрос на соединение, если таймер истекает.

Если кто-то когда-либо сталкивался с этой проблемой, мне было бы очень интересно ваше мнение и/или ваше решение, конечно.

ОБНОВЛЕНИЕ 2014-12-17:

Тем временем я работал над своим решением, используя таймеры, и, похоже, он работает очень хорошо.

Тайм-аут соединения выполняется прямо. Просто установите таймер на 5 секунд или то, что вы считаете полезным для вас. Если таймер истекает, и устройство не подключилось, просто отмените соединение и сообщите пользователю, что возникла проблема.

Обнаружение устройств, выходящих за пределы диапазона, было несколько сложнее. Для каждого обнаруженного устройства я запускаю таймер, который срабатывает через два раза, устройство отправляет рекламные объявления. Если устройство отправляет еще одно объявление до истечения таймера, оно, вероятно, выходит за пределы диапазона или отключено или подключено к другому устройству.

Я не хочу отвечать на свой вопрос, потому что надеюсь, что Apple однажды сможет позаботиться об этих проблемах.

Ответ 1

Правильный способ определить, доступно ли устройство, - сохранить периферийное значение identifier. Прежде чем пытаться восстановить соединение, вызовите retrievePeripheralsWithIdentifiers. Тем не менее, это все еще не гарантирует, что устройство будет находиться в зоне действия к моменту попытки подключения!

При попытке подключения не хватает времени на уровне ОС, и это явно документировано.

Некоторым приложениям может потребоваться использовать базовую инфраструктуру Bluetooth для выполнения долгосрочные действия в фоновом режиме. В качестве примера представьте, что вы разработка приложения для домашней безопасности для устройства iOS, которое сообщает с дверным замком (оснащен технологией Bluetooth с низким энергопотреблением). приложение и блокировка взаимодействуют, чтобы автоматически блокировать дверь, когда пользователь покидает дом и открывает дверь, когда пользователь возвращается - все, пока приложение находится в фоновом режиме. Когда пользователь уходит из дома, устройство iOS может в конечном итоге выйти из диапазона блокировки, вызывая соединение чтобы замок был потерян. На этом этапе приложение может просто вызвать connectPeripheral: options: метод класса CBCentralManager и потому что запросы на соединение не истекают, устройство iOS повторно подключиться, когда пользователь вернется домой.