Exécuter iPhone comme un iBeacon à l'arrière-plan

est-il possible de faire fonctionner un appareil iOS 7 comme un périphérique Bluetooth LE (iBeacon) et de le faire annoncer en arrière-plan? J'ai été en mesure de l'obtenir pour la publicité dans le premier plan avec le code ci-dessous et peut le voir à partir d'un autre appareil iOS, mais dès que je retourne à l'écran d'accueil il cesse la publicité. J'ai ajouté le bluetooth-périphérique de fond mode dans le plist mais cela ne semble pas aider bien que je ne reçois l'invite disant que l'appareil veut utiliser bluetooth dans le fond. Est-ce que je fais quelque chose de mal ou est-ce que ce n'est pas possible dans iOS 7?

peripManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];

- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral
{
  if (peripheral.state != CBPeripheralManagerStatePoweredOn) {
      return;
  }

  NSString *identifier = @"MyBeacon";
  //Construct the region
  CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:identifier];

  //Passing nil will use the device default power
  NSDictionary *payload = [beaconRegion peripheralDataWithMeasuredPower:nil];

  //Start advertising
  [peripManager startAdvertising:payload];
}

voici le code qui est sur la fin de réception / écoute:

- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons
           inRegion:(CLBeaconRegion *)region
{
//Check if we have moved closer or farther away from the iBeacon…
if (beacons.count > 0) {
    CLBeacon *beacon = [beacons objectAtIndex:0];

    switch (beacon.proximity) {
        case CLProximityImmediate:
            [self log:[NSString stringWithFormat:@"You're Sitting on it! %li", (long)beacon.rssi]];
            break;
        case CLProximityNear:
            [self log:[NSString stringWithFormat:@"Getting Warmer! %li", (long)beacon.rssi]];
            break;
        default:
            [self log:[NSString stringWithFormat:@"It's around here somewhere! %li", (long)beacon.rssi]];
            break;
    }
}
}
66
demandé sur jpcoder 2013-09-22 17:26:25

5 réponses

Standard CoreBluetooth les publicités diffusées pendant que l'application est en arrière-plan, mais pas si ils ont commencé avec un CLBeaconRegion le dictionnaire. La solution consiste à abandonner complètement le cadre de CoreLocation et à créer votre propre "cadre" de Proximité en utilisant uniquement le CoreBlueTooth.

vous devez toujours utiliser les spécificateurs d'arrière-plan appropriés dans L'Info.fichier plist (par exemple bluetooth-peripheral et bluetooth-central ).

le code ressemble à quelque chose comme ceci:

1) Créer une publicité périphérique standard en utilisant CBPeripheralManager

NSDictionary *advertisingData = @{CBAdvertisementDataLocalNameKey:@"my-peripheral",
                                  CBAdvertisementDataServiceUUIDsKey:@[[CBUUID UUIDWithString:identifier]]};

// Start advertising over BLE
[peripheralManager startAdvertising:advertisingData];

2) Utilisez CBCentralManager pour scanner ce service en utilisant L'UUID que vous avez spécifié.

NSDictionary *scanOptions = @{CBCentralManagerScanOptionAllowDuplicatesKey:@(YES)};
NSArray *services = @[[CBUUID UUIDWithString:identifier]];

[centralManager scanForPeripheralsWithServices:services options:scanOptions];

3) dans la CBCentralManagerDelegate méthode didDiscoverPeripheral , lire la RSSI valeur de l'annonce.

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

    NSLog(@"RSSI: %d", [RSSI intValue]);
}

4) traduire les valeurs RSSI en distance.

- (INDetectorRange)convertRSSItoINProximity:(NSInteger)proximity
{
    if (proximity < -70)
        return INDetectorRangeFar;
    if (proximity < -55)
        return INDetectorRangeNear;
    if (proximity < 0)
        return INDetectorRangeImmediate;

    return INDetectorRangeUnknown;
}

j'ai trouvé que je devais" faciliter "ou" moyenne " les valeurs RSSI pour obtenir quelque chose de réalisable. Ce n'est pas différent que lorsque vous travaillez avec des données de capteur (par exemple Données d'accéléromètre).

j'ai ce concept pleinement l'espoir de travailler pour le publier quelque part à un moment donné.

utilisez aussi le docs (Core Bluetooth Programming Guide) si vous êtes bloqué.

Mise À Jour: A le code complet de l'échantillon est sur GitHub . J'ai travaillé sur cela dans le cadre d'un projet lié au travail .

mise à Jour #2: Apple libération des améliorations majeures à iBeacon fond de comportement pour iOS7.1

47
répondu bentford 2014-03-14 22:50:10

le pouvez-vous sentir l'iBeacon? article discute à la fois l'utilisation D'Estimotes et la publicité à partir de Macs et iOS dispositifs. Vous devez vérifier la capacité "agit comme accessoire Bluetooth" dans la cible du projet.

4
répondu Cameron Lowell Palmer 2013-11-23 19:20:25

non, les appareils iOS ne font de la publicité pour iBeacon que lorsque l'application qui fait la publicité est au premier plan. donc, si vous passez à une autre application ou si l'appareil s'endort, la publicité s'arrête.

bien sûr, si vous voulez vraiment que l'annonce continue, désactivez la minuterie et faites un accès guidé pour que l'appareil iOs ne s'endorme pas et que personne ne puisse passer à une autre application.

2
répondu RawMean 2013-10-18 02:29:01

j'espère également pouvoir mettre en place mon (test) app pour annoncer un iBeacon de l'arrière-plan. Les docs sur le UIBackgroundModes info.la touche plist suggère que la touche Bluetooth-peripheral pourrait fonctionner, mais il semble qu'elle ne fonctionne pas. (Je l'ai testé il y a quelques minutes.)

ce que je fais pour le moment, c'est désactiver la minuterie, comme le suggère RawMean, puis régler la luminosité de l'écran à 0. Enfin, quand mon application de test agit comme un iBeacon, j'ajoute un handler shake event qui rallume l'écran pendant 30 secondes. L'atténuation de l'écran aussi bas qu'il ira aide à réduire le drain de la batterie un peu.

1
répondu Duncan C 2013-10-29 13:58:42

cela peut être fait. Je ne veux pas d'ingénieurs Apple en colère devant ma porte, donc je ne publierai pas l'algorithme.

en résumé, la " overflow area qui code les UUIDs de service est juste un tas d'octets qui va au-dessus de l'air. Vous pouvez sentir vous-même. En particulier, il s'agit d'un hachage court qui est ensuite représenté par un encodage à chaud unique. Plusieurs UUIDs sont communiqués en ayant plusieurs bits mis. Vous aurez collisions de cette façon. Par exemple, UUID 1001 aura le même encodage que 3333. Vous pouvez vérifier cela vous-même: avoir un iPhone diffusion UUID 1001 sur l'arrière-plan et avoir l'autre scanner pour 3333. Il va penser qu'il reçoit 3333 en effet.

0
répondu Anne van Rossum 2018-09-22 13:53:06