0 Replies
      Latest reply on Mar 18, 2020 2:26 PM by Priya_B
      Priya_B Level 1 Level 1 (0 points)

        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"):

        1. App StartsMonitoring two Beacon regions
        2. Starts Ranging Beacons if the user enters a BeaconRegion
        3. Turn on Beacon1, the app starts ranging Beacon1
        4. 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.