nspredicateibeaconnscompoundpredicateclbeacon

NSPredicate to filter beacon according to UUID, major and minor raising exception


I have a beacons array having a collection of CLBeacon and I would like to get only the beacon which matches a given uuid, major and minor in NSPredicate. Below is the code in Object C which is generating an exception because of UUID in the predicate. The code works fine if I remove the uuidPredicate from the query.

 - (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray<CLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region{

        NSPredicate *uuidPredicate = [NSPredicate predicateWithFormat:@"uuid.UUIDString == [c] %@", @"03672ce6-9272-48ea-ba54-0bf679217980"];
       //NSPredicate *uuidPredicate = [NSPredicate predicateWithFormat:@"uuid == %@", @"03672ce6-9272-48ea-ba54-0bf679217980"];
        NSPredicate *majorPredicate = [NSPredicate predicateWithFormat:@"major = %ld", 1];
        NSPredicate *minorPredicate = [NSPredicate predicateWithFormat:@"minor = %ld", 3];

        NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[uuidPredicate, majorPredicate, minorPredicate]];

        NSArray *pointABeacon = [beacons filteredArrayUsingPredicate:compoundPredicate];   

    }

The beacons array is something like

beacons (
    "CLBeacon (uuid:03672CE6-9272-48EA-BA54-0BF679217980, major:1, minor:1, proximity:1 +/- 0.07m, rssi:-61)",
    "CLBeacon (uuid:03672CE6-9272-48EA-BA54-0BF679217980, major:1, minor:2, proximity:1 +/- 0.07m, rssi:-62)",
    "CLBeacon (uuid:03672CE6-9272-48EA-BA54-0BF679217981, major:1, minor:3, proximity:2 +/- 1.64m, rssi:-53)"
)

The exception is

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[< CLBeacon 0x1c401c410 > valueForUndefinedKey:]: this class is not key value coding-compliant for the key uuid.'

How to filter the array with three parameters uuid, major and minor?


Solution

  • The error is clear: A CLBeacon object doesn't have a property named uuid.

    When you print a CLBeacon object, you might see "uuid", but that's not the real name of the property, it's proximityUUID

    So:

    NSPredicate *uuidPredicate = [NSPredicate predicateWithFormat:@"uuid.UUIDString == [c] %@", @"03672ce6-9272-48ea-ba54-0bf679217980"];
    

    should be:

    NSPredicate *uuidPredicate = [NSPredicate predicateWithFormat:@"proximityUUID.UUIDString == [c] %@", @"03672ce6-9272-48ea-ba54-0bf679217980"];