Ranging beacons with startRangingBeacons(satisfying: CLBeaconIdentityConstraint ) does not range multiple beacons.
The newer method for ranging beacons "startRangingBeacons(satisfying: CLBeaconIdentityConstraint )", will only range the most recently added beacon, so if there are more than one beacon, we have a problem. When used the older method, "startRangingBeacons(in: region)," now deprecated but still functional in iOS 13, the app works as expected.
Details (using the newer method with "constraints"):
- App StartsMonitoring two Beacon regions
- Starts Ranging Beacons if the user enters a BeaconRegion
- Turn on Beacon1, the app starts ranging Beacon1
- Turn on Beacon2, the app starts ranging Beacon2, but does not range beacon1.
(NOTE - Both beacons regions overlap)
- When ranged beacons with startRangingBeacons(in: region), the app was able to range both beacons.
- But ,while ranging beacons with the latest startRangingBeacons(satisfying: CLBeaconIdentityConstraint ), didRangeBeacons only ranges the latest beacon in range and ignores the previously ranged beacons.
As soon as I start ranging for a second
CLBeaconIdentityConstraint
, I stop receiving range updates for the beacons that match the first CLBeaconIdentityConstraint
, even though rangedBeaconConstraints
shows both the first and second constraints.Code sample:
import UIKit
import CoreLocation
class RangeBeaconViewController: UIViewController, CLLocationManagerDelegate {
var locationManager = CLLocationManager()
var beaconConstraints = [CLBeaconIdentityConstraint: [CLBeacon]]()
var beacons = [CLProximity: [CLBeacon]]()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
let firstUUID = UUID(uuidString: "a_valid_uuid")!
let firstConstraint = CLBeaconIdentityConstraint(uuid: firstUUID)
self.beaconConstraints[firstConstraint] = []
let firstBeaconRegion = CLBeaconRegion(beaconIdentityConstraint: firstConstraint, identifier: firstUUID.uuidString)
self.locationManager.startMonitoring(for: firstBeaconRegion)
let secondUUID = UUID(uuidString: "another_valid_uuid")!
let secondConstraint = CLBeaconIdentityConstraint(uuid: secondUUID)
self.beaconConstraints[secondConstraint] = []
let secondBeaconRegion = CLBeaconRegion(beaconIdentityConstraint: secondConstraint, identifier: secondUUID.uuidString)
self.locationManager.startMonitoring(for: secondBeaconRegion)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
// Stop ranging with beacon region
// for region in locationManager.monitoredRegions {
// locationManager.stopRangingBeacons(in: region as! CLBeaconRegion)
// locationManager.stopMonitoring(for: region)
// }
// Stop ranging with beaconconstraints
for constraint in beaconConstraints.keys {
locationManager.stopRangingBeacons(satisfying: constraint)
}
}
func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
let beaconRegion = region as? CLBeaconRegion
//guard let beaconRegion = region as? CLBeaconRegion else{ return }
if state == .inside {
// Start ranging with beacon Constraint
manager.startRangingBeacons(satisfying: beaconRegion!.beaconIdentityConstraint)
// Start ranging with beacon region
//manager.startRangingBeacons(in: beaconRegion)
} else {
// Stop ranging with beacon Constraint
manager.stopRangingBeacons(satisfying: beaconRegion!.beaconIdentityConstraint)
// Stop ranging with beacon region
//manager.stopRangingBeacons(in: beaconRegion)
}
}
//did range with beacon constraint
func locationManager(_ manager: CLLocationManager, didRange beacons: [CLBeacon], satisfying beaconConstraint: CLBeaconIdentityConstraint) {
beaconConstraints[beaconConstraint] = beacons
for beacon in beacons {
print("Ranging \(beacon.uuid)")
}
}
//did range with beacon region
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
beaconConstraints[region.beaconIdentityConstraint] = beacons
for beacon in beacons {
print("Ranging \(beacon.uuid)")
}
}
}
Is this a bug in CoreLocation, or am I missing anything.