2013-10-14 9 views
15

Ich schreibe eine Anwendung für iOS, die erfordert, dass die Anwendung sowohl ein iOS iBeacon ankündigen als auch periphere Dienste gleichzeitig bewerben. Es ist notwendig, dass der Dienst eher angekündigt wird, als einfach auf dem Peripheriegerät zu finden, weil der Anwendungsfall die zentrale (im BLE-Sprachgebrauch) Verbindung zum Peripheriegerät erfordert, nachdem iOS (aber immer noch im Hintergrund) wegen der Nähe zum iBeacon geweckt wurde. Apps, die im Hintergrund auf Zentralen ausgeführt werden, können Peripheriegeräte nur nach verfügbarem Dienst erkennen, anstatt alle Peripheriegeräte zu erkennen []; Mein Code funktioniert, um entweder den Dienst oder den iBeacon zu bewerben, aber ich habe nicht herausgefunden, wie man beides gleichzeitig macht. Es ist möglich, dass der iBeacon 21 Bytes der 38 Bytes verfügbaren Speicherplatzes nutzt und es nicht einfach genug Platz gibt, um einen Beacon sowie einen Dienst zu bewerben?iOS CoreBluetooth/iBeacon: Werben ein iBeacon und einen peripheren Dienst gleichzeitig

Das funktioniert (Leuchtfeuer):

self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid 
    major:1 
    minor:1 
    identifier:@"bentboolean"]; 
NSMutableDictionary *dict = [[self.beaconRegion peripheralDataWithMeasuredPower:nil] mutableCopy];  
[self.peripheralManager startAdvertising:dict ]; 

Dies funktioniert (Service):

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; 
[dict setValue:@[serviceUUID] forKey:CBAdvertisementDataServiceUUIDsKey]; 
[self.peripheralManager startAdvertising:dict ]; 

die beiden zusammen Hinzufügen, versuchen beide Dienste gleichzeitig werben nicht funktioniert. Es wirbt nur die Beacon, nicht die Dienstleistung:

self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid 
    major:1 
    minor:1 
    identifier:@"bentboolean"]; 
NSMutableDictionary *dict = [[self.beaconRegion peripheralDataWithMeasuredPower:nil] mutableCopy]; 
[dict setValue:@[serviceUUID] forKey:CBAdvertisementDataServiceUUIDsKey]; 
[self.peripheralManager startAdvertising:dict ]; 

Danke für einen Blick!

+0

Hallo, hast du das jemals behoben? Ich glaube nicht, dass es aufgrund der Kapazität von Bluetooth möglich ist ... – CW0007007

Antwort

-1

Ich konnte dies mit einem separaten CLLocationManager und CLBeaconRegion für die Empfänger beide und die Bake separat in Gang bringen:

#import "GRBothViewController.h" 

@interface GRBothViewController() 

@end 

@implementation GRBothViewController 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 


    self.locationManager = [[CLLocationManager alloc] init]; 
    self.locationManager.delegate = self; 

    self.locationScanner = [[CLLocationManager alloc] init]; 
    self.locationScanner.delegate = self; 

    [self initBeacon]; 
    [self initRegion]; 
    [self locationManager:self.locationManager didStartMonitoringForRegion:self.scannerRegion]; 
} 

- (void)initBeacon { 
    NSLog(@"Starting beacon"); 

    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString: @"23542266-18D1-4FE4-B4A1-23F8195B9D39"]; 
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid 
                   major:1 
                   minor:1 
                  identifier:@"com.thisisgrow.Grow"]; 
    [self transmitBeacon:self]; 
} 

- (IBAction)transmitBeacon:(id)sender { 
    self.beaconPeripheralData = [self.beaconRegion peripheralDataWithMeasuredPower:nil]; 
    self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self 
                    queue:nil 
                    options:nil]; 
} 

-(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { 
    if (peripheral.state == CBPeripheralManagerStatePoweredOn) { 
     NSLog(@"Powered On"); 
     [self.peripheralManager startAdvertising:self.beaconPeripheralData]; 
    } else if (peripheral.state == CBPeripheralManagerStatePoweredOff) { 
     NSLog(@"Powered Off"); 
     [self.peripheralManager stopAdvertising]; 
    } 
} 

- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region { 
    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion]; 
} 

- (void)initRegion { 
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"23542266-18D1-4FE4-B4A1-23F8195B9D39"]; 
    _scannerRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"com.thisisgrow.Grow"]; 
    _scannerRegion.notifyEntryStateOnDisplay = YES; 
    [_locationScanner startMonitoringForRegion:self.scannerRegion]; 
} 

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region { 
    //SCANNER 
    [self.locationScanner startRangingBeaconsInRegion:self.scannerRegion]; 
} 

-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region { 
    //SCANNER HAS LEFT THE AREA 
    [self.locationScanner stopRangingBeaconsInRegion:self.scannerRegion]; 
} 

-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region { 
    CLBeacon *beacon = [[CLBeacon alloc] init]; 
    NSLog(@"Beacons: %d", [beacons count]); 
    if(beacons && [beacons count]>0){ 
     beacon = [beacons firstObject]; 
    } 
    else{ 

    } 
} 

Die einzige Einschränkung dabei ist, dass das Gerät selbst nicht erkennen kann.

+0

Eine andere interessante Beobachtung, die ich gesehen habe: selbst wenn * eine andere App als iBeacon wirbt, kann deine App es nicht erkennen. Wenn ein externer iBeacon vorhanden ist, der die gleichen Bezeichner anzeigt, kann Ihre App diese weiterhin nicht erkennen. Mit anderen Worten, die Werbung für einen iBeacon-ID-Satz blockiert alle Erkennungen desselben ID-Satzes. – davidgyoung

+0

Wahr genug, aber wenn ein Gerät als iBeacon verwendet wird, ist es einfach genug, um automatisch eine eindeutige UUID für das Gerät zu generieren (sogar beim Start, falls gewünscht), wenn Sie sie für diesen Zweck verwenden möchten. Die meisten einschränkenden Faktoren sind die Tatsache, dass 1) ein Gerät als iBeacon wird nicht im Hintergrund AT ALL, und 2) Anwendungen können nicht für einzelne iBeacons im Hintergrund reichen, außer wenn auf OnEnter aufgewacht und onLeave Ereignisse, die nur ausgelöst werden, wenn UUID-Regionen betreten oder verlassen werden. – d2burke

+0

@ d2burke Sie erwähnen, dass ein Gerät, das als iBeacon verwendet wird, überhaupt nicht im Hintergrund gesendet wird. Weißt du, ob dies der Fall ist, selbst wenn die App den Bluetooth-Peripheral-Hintergrundmodus verwendet? – darrinm

0

In meiner Praxis kann iBeacon & BLE-Dienst nicht zur gleichen Zeit werben.

Der BLE-Dienst kann nicht im Vordergrund werben, wenn Werbung mit iBeacon gemischt wird. iBeacon kann nicht im Hintergrund werben.

iBeacon & BLE-Dienst kann einzeln, z. iBeacon werben 0,5 Sekunden, dann BLE Service werben 30,0 Sekunden.

Hoffe, das wird hilfreich