Я хотел бы разработать приложение, которое обнаруживает много маяковых устройств, не зная uuid. Однако я не могу найти способ сделать это. Мне нужно определить uuid в коде.

Я разработал POC, который работает с известными устройствами.

Мой код контроллера представления:

-(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;  
    }  
}

Так есть ли способ обнаружить iBeacon, не зная uuid?

Примечание. Пример приложения, использующего ту же функцию, что и , отметьте эту ссылку широковещательные радиовещательные сигналы (виртуальные маяки).

Любая помощь будет высоко ценится.

5
Merry 11 Май 2016 в 16:24

3 ответа

Лучший ответ

В iOS нет общедоступных API-интерфейсов для обнаружения маяков, если предварительно не известен хотя бы ProximityUUID маяка. Это сделано намеренно - Apple хочет, чтобы вы могли видеть только свои собственные маяки, что означает знание ProximityUUID.

Тем не менее, операционная система определенно знает, как увидеть любой маяк, и могут быть частные API, которые вы можете использовать для этого . Просто поймите, что вы не можете использовать частные API для разработки приложения для App Store, поскольку Apple не одобрит использование такого кода. Вы можете использовать частные API-интерфейсы, чтобы создать утилиту для использования на вашем собственном устройстве iOS, но частные API-интерфейсы могут перестать работать при любом обновлении iOS.

С учетом этих оговорок, используя CoreLocation, можно определить подстановочный знак CLBeaconRegion, который можно использовать для поиска любого маяка с использованием частного API. См. здесь один подход.

12
davidgyoung 11 Май 2016 в 14:16

Вам необходимо использовать библиотеку CoreBluetooth для поиска устройств. Как только вы найдете свой iBeacon в списке обнаруженных устройств, вам нужно будет запросить сервисы и характеристики iBeacon, чтобы найти UUID. Вот как я это сделал:

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.
        }
    }
1
Simon Germain 20 Мар 2017 в 14:34

Я тоже искал такой же & amp; Я получил свой ответ на этот пример введите здесь описание ссылки

Это ищет все iBeacon без UUID

0
Chaaruu Jadhav 8 Фев 2018 в 13:07