iOS8 RSSI and Proximity unexpected results

320 Views Asked by At

I am using CoreLocation to detect 4 specific beacons in my classroom, unfortunately, no matter how I move and how close I am to the beacon, CoreLocation provides me with proximity: 0, +/- -1.00m and RSSI: 0.

The code in my controller is this:

func centralManagerDidUpdateState(central: CBCentralManager) {
        if(central.state == CBCentralManagerState.PoweredOn){
            print("Powered on")
        }
        else if(central.state == CBCentralManagerState.PoweredOff){
            print("Powered off")
        }
        else if(central.state == CBCentralManagerState.Unknown){
            print("Unknown state")
        }
    }

    func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) {
        print(peripheral)
    }

    func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
        print(advertisementData)
    }

    func locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion) {
        var knownBeacons = beacons.filter{$0.proximity != CLProximity.Unknown}
        if(knownBeacons.count > 0){
            closestBeacon = knownBeacons[0] as CLBeacon
        }

        print(beacons)

        for beacon in beacons{
            print(beacon.proximity.rawValue)
        }
    }

EDIT: After some debugging I found out that the methods didConnectPeripheral and didDiscoverPeripheral are not being called by iOS on iPhone.

1

There are 1 best solutions below

2
On

In case you correctly print out the CLBeacon information, one problem can be the advertising frequency of the beacons you have. If they broadcast at a very low frequency (once per second or less), then iOS will have a hard time figuring out accurate values for RSSI and proximity.

Regarding your CBCentralManager question, you have to explicitly call scanForPeripheralsWithServices:options: to start the scan and then stopScan. You want to call stopScan for at least two reasons: scanning drains battery and after a couple of seconds you will receive all the information you need about the BLE peripherals around you. You can stop the scan with a timer or manually from UI. After you've received the information about the peripherals, then you can issue connect on them. Only then you'll get notification on didConnectPeripheral delegate method.