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.
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 callscanForPeripheralsWithServices:options:
to start the scan and thenstopScan
. You want to callstopScan
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 ondidConnectPeripheral
delegate method.