Core Bluetooth anuncia y escanea en segundo plano

He estado intentando configurar una aplicación para que el dispositivo busque periféricos y se anuncie como periférico. El objective es que se despierten dos dispositivos en segundo plano cuando se acerquen el uno al otro mediante el descubrimiento de bluetooth. A partir de la documentación de Apple, parece que debería poder ejecutar BLE en segundo plano (con los modos de fondo bluetooth-central y bluetooth-periféricos habilitados), y mi aplicación funciona cuando un dispositivo está en primer plano. En primer lugar, anuncio datos de esta manera:

NSDictionary *advertisingData = @{CBAdvertisementDataLocalNameKey:@"my-peripheral", CBAdvertisementDataServiceUUIDsKey:@[[CBUUID UUIDWithString:identifier]]}; // Start advertising over BLE [peripheralManager startAdvertising:advertisingData]; 

Luego configuré el dispositivo para buscar datos:

 NSArray *services = @[[CBUUID UUIDWithString:identifier]]; [centralManager scanForPeripheralsWithServices:services options:nil]; 

Sin embargo, cuando ambos entran en segundo plano (el dispositivo debe estar bloqueado), el bluetooth no puede descubrir y

 - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI 

nunca recibe llamadas en ninguno de los dispositivos. ¿Cómo puedo arreglar esto? Gracias

Me temo que lo que estás tratando de hacer no funcionará. He tratado de lograr lo mismo.

El problema es la diferencia en el escaneo en primer plano y fondo. Cuando escanea dispositivos en primer plano, puede buscar cualquier cosa. En segundo plano, debe especificar el UUID de servicio real que está escaneando. Ok, esto no es realmente un problema ya que conoces el UUID que estás buscando.

Periférico: la radiodifusión como periférico funciona de manera diferente en primer plano y en segundo plano. En primer plano funciona como cualquier periférico BT normal. En segundo plano, tiene una cantidad de espacio muy limitada para trabajar, por lo que el UUID de sus periféricos está oculto y no se transmite. Solo cuando un dispositivo central (un iPhone en primer plano) solicita la información, se activará su aplicación y se mostrará su UUID.

Entonces los 2 se cancelan mutuamente. Como su exploración de fondo solo puede explorar dispositivos con un UUID específico y su periférico de fondo no puede anunciar su UUID, no pueden verse entre sí.

1 de sus dispositivos (periféricos o centrales) debe estar en primer plano para funcionar.

Esto se ha discutido varias veces en la lista de correo de Bluetooth de Apple.

Debería explicar cómo está probando esto, porque teóricamente parece que debería funcionar. Hay dos problemas principales que puede enfrentar:

1.) El escaneo se acelera cuando los dispositivos iOS están en segundo plano.

  • Si bien el escaneo en primer plano probablemente descubra inmediatamente un dispositivo publicitario junto a él, el descubrimiento en segundo plano puede demorar hasta ~ 60 veces más. El sistema iOS no supone que el usuario prefiera que una aplicación tenga una mejor funcionalidad Bluetooth que otra (o que solo una aplicación quiera usarla). Y dado que es una funcionalidad compartida, quieren que los usuarios tengan una experiencia uniforme en todas las aplicaciones. Debería consultar las especificaciones técnicas sobre los intervalos de publicidad y escaneo para tener una mejor idea de lo que Apple tiene que hacer bajo las sábanas.

2.) Es posible que sus dispositivos ya se hayan descubierto antes de ingresar al fondo.

  • Debemos recordar que Apple inhabilita el CBCentralManagerScanOptionAllowDuplicatesKey exploración CBCentralManagerScanOptionAllowDuplicatesKey cuando ingresamos el fondo. Ya que ni siquiera está especificando esta bandera, de todos modos es NO. Entonces, si se han visto una vez, no recibirán otra callback cuando estén en segundo plano.

Personalmente necesitaba una característica así y desarrollé un componente de código abierto: https://github.com/omergul123/Discovery

Puede ser muy útil si desea intercambiar una ID, incluso si las aplicaciones iguales se ejecutan en segundo plano.