2016-05-11 6 views
4

Ich möchte App entwickeln, die eine Menge von Beacon-Gerät erkennt, ohne Uuid zu kennen. Jedoch kann ich keinen Weg finden, dies zu tun. Ich muss UUID im Code definieren.Wie kann ich Ibeacon-Gerät erkennen, ohne UUID in iOS zu kennen?

Ich habe eine POC entwickelt, die mit bekannten Geräten funktioniert.

Code My-View-Controller:

-(void)setUpview 
{ 
    // Regardless of whether the device is a transmitter or receiver, we need a beacon region. 
    NSUUID * uid = [[NSUUID alloc] initWithUUIDString:@"78CDC73D-D678-4B35-A88A-C2E09E5B963F"];//[UIDevice currentDevice].identifierForVendor; 
    treasureId = @"com.eden.treasure"; 
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uid identifier:treasureId]; 

    // Location manager. 
    self.locationManager = [[CLLocationManager alloc] init]; 
    self.locationManager.delegate = self; 

    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { 
     [self.locationManager requestAlwaysAuthorization]; 
    } 

    [self.locationManager startMonitoringForRegion:self.beaconRegion]; 
    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion]; 
    [self locationManager:self.locationManager didStartMonitoringForRegion:self.beaconRegion]; 

    [self.beaconRegion setNotifyEntryStateOnDisplay:YES]; 
    [self.beaconRegion setNotifyOnEntry:YES]; 
    [self.beaconRegion setNotifyOnExit:YES]; 

// self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil]; 
    if ([UIDevice currentDevice].userInterfaceIdiom==UIUserInterfaceIdiomPad || [[[UIDevice currentDevice] model] isEqualToString:@"iPad Simulator"]) 
    { 
     [self configureTransmitter]; 
    } 
    else { 
     [self configureReceiver]; 
    } 
} 


-(void)configureTransmitter 
{ 
    // The received signal strength indicator (RSSI) value (measured in decibels) for the device. This value represents the measured strength of the beacon from one meter away and is used during ranging. Specify nil to use the default value for the device. 
    NSNumber * power = [NSNumber numberWithInt:-63]; 
    self.peripheralData = [self.beaconRegion peripheralDataWithMeasuredPower:power]; 
    // Get the global dispatch queue. 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    // Create a peripheral manager. 
    self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:queue]; 
} 

-(void)configureReceiver { 
    // Location manager. 
    self.locationManager = [[CLLocationManager alloc] init]; 
    self.locationManager.delegate = self; 
    [self.locationManager requestAlwaysAuthorization]; 
    [self.locationManager startMonitoringForRegion:self.beaconRegion]; 
    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion]; 
} 
#pragma mark - CBPeripheralManagerDelegate methods 

-(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral 
{ 
    // The peripheral is now active, this means the bluetooth adapter is all good so we can start advertising. 
    if (peripheral.state == CBPeripheralManagerStatePoweredOn) 
    { 
     [self.peripheralManager startAdvertising:self.peripheralData]; 
    } 
    else if (peripheral.state == CBPeripheralManagerStatePoweredOff) 
    { 
     NSLog(@"Powered Off"); 
     [self.peripheralManager stopAdvertising]; 
    } 
} 
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region 
{ 
    if(state == CLRegionStateInside) 
    { 
     NSLog(@"%@",[NSString stringWithFormat:@"You are inside region %@", region.identifier]); 
    } 
    else if(state == CLRegionStateOutside) 
    { 
     NSLog(@"%@",[NSString stringWithFormat:@"You are outside region %@", region.identifier]); 
    } 
    else 
    { 
     return; 
    } 
} 

-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region 
{ 
    if ([beacons count] == 0) 
     return; 

    NSString * message; 
    UIColor * bgColor; 
    CLBeacon * beacon = [beacons firstObject]; 

    switch (beacon.proximity) { 
     case CLProximityUnknown: 
      message = [NSString stringWithFormat:@"ProximityUnknown -- %ld", (long)beacon.proximity]; 
      bgColor = [UIColor blueColor]; 
      break; 
     case CLProximityFar: 
      message = [NSString stringWithFormat:@"ProximityFar -- %ld", (long)beacon.proximity]; 
      bgColor = [UIColor colorWithRed:.0f green:.0f blue:230.0f alpha:1.0f]; 
      break; 
     case CLProximityNear: 
      message = [NSString stringWithFormat:@"ProximityNear -- %ld", (long)beacon.proximity]; 
      bgColor = [UIColor orangeColor]; 
      break; 
     case CLProximityImmediate: 
     default: 
      message = [NSString stringWithFormat:@"ProximityImmediate -- %ld", (long)beacon.proximity]; 
      bgColor = [UIColor redColor]; 
      break; 
    } 
    if (beacon.proximity != self.previousProximity) 
    { 
     [lblStatus setText:message]; 
     [self.view setBackgroundColor:bgColor]; 
     self.previousProximity = beacon.proximity; 
    } 
} 

So ist es eine Möglichkeit, IBeacon zu erfassen, ohne zu wissen, UUID?

Hinweis: Beispielanwendung, die die gleiche Funktion wie check This link Broadcastsendung (Virtual Beacons) verwendet.

Jede Hilfe würde sehr geschätzt werden.

+0

Sie sollten nicht in der Lage sein, es zu tun. Wenn es ein REAL iBeacon ist (und kein Hybrid zwischen einem klassischen BLE-Gerät und einem iBeacon). iOS sollte die BLE-Broadcast-Nachricht automatisch übersetzen und sie nur für CLBeacon-Dateien verfügbar machen. Wenn es sich um einen Hybrid handelt, der manchmal klassisches BLE-Material sendet, können Sie es mit CBPeripheralManager finden und die UUID nach CLBeacon durchsuchen lassen. Das Hauptproblem ist, dass iOS nur High-Level-APIs und keine Low-Level-APIs bereitstellt, während sie für Android die Nachricht selbst analysieren und so scannen und als Reaktion darauf reagieren können, was immer sie wollen. – Larme

+0

Sie müssen wissen, die UUID, die Sie suchen. Sie können nicht nach allen UUIDs scannen – Paulw11

Antwort

9

Es gibt keine öffentlichen APIs in iOS, um Beacons zu erkennen, ohne zuvor mindestens die ProximityUUID des Beacons zu kennen. Das ist Absicht - Apple möchte nur, dass Sie Ihre eigenen Beacons sehen können, was bedeutet, dass Sie die ProximityUUID kennen.

Das gesagt, das Betriebssystem weiß sicherlich, wie man jede Beacon und kann private APIs, die Sie verwenden können, um dies zu tun. Beachten Sie, dass Sie keine privaten APIs verwenden können, um eine App für den App Store zu entwickeln, da Apple die Verwendung eines solchen Codes nicht genehmigt. Sie können private APIs verwenden, um ein Dienstprogramm zu machen für Ihr eigenes iOS-Gerät verwenden, aber die privaten APIs stoppen können mit jedem iOS arbeitet Upgrade

Mit diesen Einschränkungen angegeben, CoreLocation mit ihm möglich sein kann CLBeaconRegion einen Platzhalter zu definieren, dass seine verwendet, um nach einem Beacon zu suchen, das eine private API verwendet. See here für einen Ansatz.

+0

Sie haben Recht, wir haben das obige Beispiel getestet und es werden korrekte Ergebnisse angezeigt, einschließlich iBeacons/virtuelle iBeacons mit verschiedenen UUIDs. Da es sich jedoch um eine private API handelt, ist dies für die tatsächliche Entwicklung nicht hilfreich. Irgendwelche Möglichkeiten Danke für Informationen. Schätzen. – Merry

+0

Hallo zusammen, ich bin neu, also hatte ich einige Fragen über die Integration von iBeacon mit iOS. Ist es möglich, diese iBeacons ohne MinorID zu verfolgen (während wir nur MajorID haben)? Wenn dies möglich ist, wie sieht es im Code aus? Und wie kann man diese an verschiedenen Orten oder Zonen verfolgen? –

+0

Ja, das ist möglich.Sie tun dies einfach, indem Sie die Minor-Null in der Regionsdefinition belassen. – davidgyoung

1

Sie müssen die Bibliothek CoreBluetooth verwenden, um nach Geräten zu suchen. Sobald Sie Ihren iBeacon aus der Liste der erkannten Geräte gefunden haben, müssen Sie die iBeacon-Dienste und -Eigenschaften abfragen, um die UUID zu finden. Hier ist, wie ich es tat:

import CoreBluetooth 
import CoreLocation 

extension Data { 

    public var hexString: String { 
     var str = "" 
     enumerateBytes { (buffer, index, stop) in 
      for byte in buffer { 
       str.append(String(format: "%02X", byte)) 
      } 
     } 
     return str 
    } 
} 

class viewController: UIViewController, CLLocationManagerDelegate, CBCentralManagerDelegate, CGPeripheralDelegate { 

    var locationManager: CLLocationManager = CLLocationManager() 
    var myBeaconRegion: CLBeaconRegion! 
    var centralManager: CBCentralManager! 
    var discoveredPeripheral: CBPeripheral? 

    override viewDidLoad() { 

     centralManager = CBCentralManager(delegate: self, queue: nil) 
    } 

    func centralManagerDidUpdateState(_ central: CBCentralManager) { 

     if central.state != .poweredOn { 
      return 
     } 

     centralManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicateKeys: true]) 
    } 

    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) { 

     if (RSSI.intValue > -15 || RSSI.intValue < -35) { 
      return // With those RSSI values, probably not an iBeacon. 
     } 

     if peripheral != discoveredPeripheral { 
      discoveredPeripheral = peripheral // Need to retain a reference to connect to the beacon. 
      centralManager.connect(peripheral, options: nil) 
      central.stopScan() // No need to scan anymore, we found it. 
     } 
    } 

    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { 

     peripheral.discoverServices(nil) 
    } 

    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) { 

     discoveredPeripheral = nil 
    } 

    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { 

     guard error == nil else { 
      return 
     } 

     if let services = peripheral.services { 
      for service in services { 
       peripheral.discoverCharacteristics(nil, for: service) 
      } 
     } 
    } 

    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { 

     guard error == nil else { 
      return 
     } 

     if let characteristics = service.characteristics { 
      for characteristic in characteristics { 
       if characteristic.uuid.uuidString == "2B24" { // UUID 
        peripheral.readValue(for: characteristic) 
       } 
      } 
     } 
    } 

    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { 

     guard error == nil else { 
      return; 
     } 

     if value = characteristic.value { 
      // value will be a Data object with bits that represent the UUID you're looking for. 
      print("Found beacon UUID: \(value.hexString)") 
      // This is where you can start the CLBeaconRegion and start monitoring it, or just get the value you need. 
     } 
    } 
+0

Ich habe versucht, Ihren Code .. Dieser Code ändert Wert der Kennung wegen "Str.append (String (Format:"% 02X ", Byte))" ... Bitte überprüfen Sie die Hex-Konvertierung einmal .. – chaaruu

Verwandte Themen