2016-04-03 3 views
0

Я работаю над проектом, чтобы отобразить список всех устройств BlueTooth Light с услугами с конкретными UUID. В методе didDiscoverPeripheral я сохраняю обнаруженные периферийные устройства, которые рекламируются. Я использую параметр dictionaryWithObjectsAndKeys: [NSNumber numberWithBool: NO] при сканировании для периферийных устройств. У меня есть NSTimer, чтобы просыпаться каждые 30 секунд, чтобы обновить список обнаруженных периферийных устройств и посмотреть, все ли все периферийные устройства по-прежнему рекламируются. Я использую метод retrievePeripheralsWithIdentifiers, который передается в массиве NSUUID обнаруженных и сохраненных периферийных устройств. Этот метод должен возвращать массив CBPeripherals, которые все еще рекламируются. Но он возвращает исходный массив всех периферийных устройств, которые я передаю в качестве аргумента, и никогда не сортирует периферийные устройства, которые больше не являются рекламой. Я использую этот метод неправильно? savedPeripherals - это NSDictionary, где идентификатор устройства - это ключ, а CBPeripheral - значение.CBCentralManager, чтобы получить динамический список рекламных конструкций BlueTooth Light в iOS

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:30 
           target:self 
           selector:@selector(updateActivePeripherals:) 
           userInfo:nil 
           repeats:YES]; 
- (void) updateActivePeripherals:(NSTimer *)timer 
{ 
NSMutableArray *peripherals = [[NSMutableArray alloc]init]; 
if (self.savedPeripherals.count > 0) 
{ 
for(id key in self.savedPeripherals) 
{ 
CBPeripheral *item = [self.savedPeripherals objectForKey:key]; 
NSString *identifier=[NSString stringWithFormat:@"%@", [[item identifier] UUIDString]]; 
NSUUID *id=[[NSUUID alloc]initWithUUIDString:identifier]; 
if (id) 

[периферийные устройства addObject: id]; }

} 
if (peripherals.count > 0) 
{ 
NSArray *list =[_centralManager retrievePeripheralsWithIdentifiers:peripherals]; 
} 

}}

ответ

2

documentation не утверждает, что retrievePeripheralsWithIdentifiers будет возвращать периферийные устройства, которые до сих пор видны/реклама. Скорее, он говорит, что возвращает:

Список периферийных устройств, которые центральный менеджер может сопоставлять с указанными идентификаторами.

Центральный менеджер вернет известные периферийные устройства, даже если периферийное устройство в настоящее время не видно. Это позволяет приложениям автоматически подключаться к определенному периферийному устройству, когда оно становится видимым. Рабочий процесс выглядит следующим образом:

  1. запуски приложений и извлекают желаемые периферический идентификатор (например, от NSUserDefaults)
  2. Применения запрашивает CBPeripheral с помощью retrievePeripheralsWithIdentifiers
  3. Применения выдает connect к этому периферийному
  4. Если периферийное устройству в настоящее время отображается, то соединение происходит немедленно, и метод делегата называется
  5. Если периферийное устройство в настоящее время не видно, соединение будет происходить, когда/если peri pheral становится видимым, и будет вызван метод делегата.

Для достижения требуемой функциональности вам необходимо использовать CBCentralManagerScanOptionAllowDuplicatesKey:YES и сохранить возраст против каждого периферийного устройства. Например, вы можете использовать следующий подход:

  1. Настройка словаря, введенные периферическим идентификатор
  2. Когда периферийный видно, хранить NSNumber в словаре со значением 30, а также хранить периферийное в исходный массив вашего табличного представления, если необходимо
  3. Настройте NSTimer для стрельбы каждую секунду.
  4. Каждый раз, когда срабатывает таймер, перейдите по словарю и уменьшает значение, хранящееся против каждого ключа
  5. Для каждого значения, которое декрементируется 0, удалить его из массива Tableview и обновлять Tableview
+0

То, что Я думал о том, чтобы сделать, но я надеялся на немного менее ресурсный интенсивный подход. Установка опции dictionaryWithObjectsAndKeys в YES быстро разряжает батарею i-Phone. Спасибо за такой быстрый ответ! – Alina

+0

Ну, этот вариант вступает в силу только тогда, когда ваше приложение находится на переднем плане, а Bluetooth-радио не разряжает аккумулятор, который быстро по сравнению с дисплеем. Это ваш единственный вариант, если вы хотите отображать видимые периферийные устройства. Это тот же процесс, что и iOS в любом случае необходимо будет выполнять внутри, если бы он предоставил вам список видимых периферийных устройств, за исключением того, что он должен был делать это все время, чтобы иметь возможность отвечать на запрос приложения; который никогда не может прийти, поэтому он будет менее эффективным, чем ваше приложение, выполняющее его по мере необходимости – Paulw11