Core Bluetooth - постоянные обновления RSSI на внутренних устройствах

Я только начал с базовой платформы bluetooth для iOS, и я разрабатываю приложение, которое нужно постоянно проверять на устройства BLE, чтобы я мог каждый день получать их номер RSSI.

В настоящее время у меня есть:

manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
[manager scanForPeripheralsWithServices:nil options:options];

это начинает сканирование приложения для устройств BLE и вызывает этот метод делегата при обнаружении устройства:

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    NSLog(@"Did discover peripheral. peripheral: %@ rssi: %@, UUID: %@ advertisementData: %@ ", peripheral, RSSI, peripheral.UUID, advertisementData);
    //Do something when a peripheral is discovered.

    rssiLabel.text = [RSSI stringValue];

    [manager retrievePeripherals:[NSArray arrayWithObject:(id)peripheral.UUID]];}

этот метод получает мне периферийный номер RSSI, который я могу отобразить. Затем последняя строка вызывает этот метод делегата:

- (void) centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals {

    NSLog(@"Currently known peripherals :");
    int i = 0;
    for(CBPeripheral *peripheral in peripherals) {
        NSLog(@"[%d] - peripheral : %@ with UUID : %@",i,peripheral,peripheral.UUID);

    }

     NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
     [manager scanForPeripheralsWithServices:nil options:options];

}

Этот код, кажется, работает и выполняет сканирование примерно каждые 1 минуту, но я точно не знаю, почему он работает...

Документация по базовому bluetooth довольно скудна, поэтому, если кто-нибудь знает, как это сделать, или имеет лучший способ сделать то, что я пытаюсь выполнить, я был бы благодарен за помощь!

Ответ 1

Вы пытались изменить параметр сканирования на ДА?

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber  numberWithBool:YES], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
[manager scanForPeripheralsWithServices:nil options:options];

Если вы это сделаете, вы получите свой обратный вызов "didDiscoverPeripheral" с каждым рекламным пакетом, который будет отображаться на вашем iPhone, который обычно составляет примерно каждые 100 мс (хотя я вижу, что это время обратного вызова сильно варьируется для одного и того же устройства). Это включает в себя RSSI каждого устройства, которое он видит.

Это будет намного быстрее, чем ваш 1-минутный курс обновления.

Ответ 2

Насколько я вижу, это должно делать то, что вы хотите.

Когда вы начали сканирование периферийных устройств с помощью оригинального вызова, ваш делегат должен начать получать звонки всякий раз, когда обнаружено устройство BLE. Это будет продолжаться до тех пор, пока вы не прекратите сканирование с помощью вызова

[manager stopScan];

Я не думаю, что вам действительно нужен второй вызов scanForPeripheralsWithServices в вашем методе centralManager: didRetrievePeripherals, поскольку, насколько мне известно, сканирование не останавливается, пока вы его не скажете. Тем не менее, я все еще начинаю с этого, и еще может быть тайм-аут, который я еще не нашел.

Я уверен, что причина, по которой вы звоните примерно раз в минуту, - это то, что устройство BLE рекламирует это часто. Если он рекламирует чаще, например устройство в режиме обнаружения, я думаю, что вы будете чаще звонить. Мне было бы интересно, если бы вы это подтвердили. Если устройство имеет режим обнаружения, вы можете попробовать запустить его, чтобы узнать, ускоряются ли уведомления.

Ответ 3

Вам не следует делать непрерывное сканирование, поскольку это очень дорого для власти. Как только вы обнаружили устройства, у вас есть массив объектов CBPeripheral, возвращенных вам. На CBPeripheral вы можете читать RSSI и получать обратный вызов при изменении RSSI. См. Следующую документацию: http://developer.apple.com/library/mac/#documentation/CoreBluetooth/Reference/CBPeripheralDelegate_Protocol/translated_content/CBPeripheralDelegate.html

Ответ 4

Быстрое внедрение решения @Anders:

manager.scanForPeripheralsWithServices(nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey : NSNumber(value: true)])