Question

I'm testing iBeacon, I've used didDetermineState: method and the CLRegionState is CLRegionStateUnknown when I'm inside the region, can anybody tell me why?

My Bluetooth is On and detecting the beacons when I range them for CLBeaconStateUnknown, sender and receiver are in range (1 Meter), here is my Implementation

-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{

    switch (state) {
    case CLRegionStateInside:
        currentBeconRegion = (CLBeaconRegion *)region;
        [self.locationManager startRangingBeaconsInRegion:currentBeconRegion];
        NSLog(@"INSIDE the Region");//not logging
        break;
    case CLRegionStateOutside:
        NSLog(@"OUTSIDE the Region");
        break;
    case CLRegionStateUnknown:
    default:
        NSLog(@"Region state UNKNOWN!!!"); //Logging on console
        statusLabel.text = @"Region state UNKNOWN!!!";
    //[self.locationManager stopRangingBeaconsInRegion:beaconRegion];           
    [self.locationManager startRangingBeaconsInRegion:beaconRegion];//Suceessfully ranging the beacon

        break;
    }
}
Was it helpful?

Solution 2

I've restarted both of my devices and reinstalled the app, still running into the same problem and also its not firing didEnterRegion: and didExitRegion:.

- (void)viewDidLoad
 {

 [super viewDidLoad];    
//set peripheralManager delegate
self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self
                                                                 queue:nil
                                                               options:nil];


//Set location managaer delegate
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;


uuid = [[NSUUID alloc] initWithUUIDString:@"E01D235B-A5DB-4717-8D2F-28D5B48931F1"];

// Setup a new region with that UUID and same identifier as the broadcasting beacon
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"testRegion"];
self.beaconRegion.notifyEntryStateOnDisplay = YES;
self.beaconRegion.notifyOnEntry = YES;
self.beaconRegion.notifyOnExit = YES;

}


#pragma mark -
#pragma mark - Peripheral Manager Delegates

-(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral
{
switch (peripheral.state) {
    case CBPeripheralManagerStatePoweredOn:
        [self.locationManager startMonitoringForRegion:self.beaconRegion];
        break;
    case CBPeripheralManagerStatePoweredOff:
         statusLabel.text = @"Bluetooth is Off";
        [self clearFileds];
        [self.locationManager stopMonitoringForRegion:self.beaconRegion];
        break;
    case CBPeripheralManagerStateUnknown:
    default:
        statusLabel.text = @"Bluetooth is Unsupported";
        [self clearFileds];
        [self.locationManager stopMonitoringForRegion:self.beaconRegion];
        break;
   }

 }

#pragma mark -
#pragma mark - Location Manager Delecate Methods

-(void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
{

[self.locationManager requestStateForRegion:self.beaconRegion];

}

 -(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{

switch (state) {
    case CLRegionStateInside:
        currentBeconRegion = (CLBeaconRegion *)region;
        [self.locationManager startRangingBeaconsInRegion:currentBeconRegion];
        NSLog(@"INSIDE the Region");
        break;
    case CLRegionStateOutside:
        NSLog(@"OUTSIDE the Region");
        break;
    case CLRegionStateUnknown:
    default:
        NSLog(@"Region state UNKNOWN!!!");
        statusLabel.text = @"Region state UNKNOWN!!!";
       [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
        break;
    }
}
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
//check if we're ranging the correct beacon
if (![self.beaconRegion isEqual:region]) { return;}

NSLog(@"didEnterRegion");
if([region isKindOfClass:[CLBeaconRegion class]])
{
    currentBeconRegion = (CLBeaconRegion *)region;
    if ([beaconRegion.identifier isEqualToString:@"testRegion"])
    {

        //send local notificaation
        UILocalNotification *notice = [[UILocalNotification alloc] init];
        notice.alertBody = @"Becoan Found!!!";
        notice.alertAction =@"View";
        [[UIApplication sharedApplication] presentLocalNotificationNow:notice];

        //srart raning beacon region
        [self.locationManager startRangingBeaconsInRegion:currentBeconRegion];


        }
    } 

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

if ([beacons count] > 0) {

    int major = [beacons.firstObject major].intValue;
    int minor = [beacons.firstObject minor].intValue;

    if (major != self.foundBeacon.major.intValue || minor !=     self.foundBeacon.minor.intValue) {
        NSLog(@"Found Beacon is: %@", [beacons firstObject]);
    }

    self.foundBeacon = [[CLBeacon alloc] init];
    self.foundBeacon = [beacons firstObject];
    //Set the ui
    [self setFileds];

 }
else //[beacon count]  0
{
    statusLabel.text = @"No becaons found";
    [self clearsFileds];
   // [self.locationManager stopMonitoringForRegion:beaconRegion];
    }

}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
NSLog(@"didExitRegion");
if([region isKindOfClass:[CLBeaconRegion class]])
{
    currentBeconRegion = (CLBeaconRegion *)region;
    if ([beaconRegion.identifier isEqualToString:@"testRegion"])
    {
        [self.locationManager stopMonitoringForRegion:currentBeconRegion];

     }
  }
}

OTHER TIPS

You say you are "inside the region" but how do you know the iBeacon is really being detected? Is Bluetooth turned on and working? Has the user allowed location access when prompted?

I would enable iBeacon ranging and log anything detected to verify your device really is seeing the iBeacon. I suspect you will either find you do not detect anything, or perhaps the iBeacon.proximity field will be returning CLProximityUnknown due to a bad calibration.

The didDetermineState gets an extra call even if no beacons have ever been detected when you start up monitoring (or if you awake the screen when notifyEntryStateOnDisplay=YES is set on you region). This is the only case where I would think you might get a CLRegionStateUnknown value. I have never seen this value returned, so I am curious under what conditions it happens. Finding the answers to my questions above may solve this. Please report back!

This post was written based on iOS 8 this may change in the future:

I'm posting an answer here in case someone else is having the same problem as me. I spent almost 4 hours on this in total before realizing that it was because my phone was in airplane mode.

tl;dr

If airplane mode is on, region notifications don't come through

I had the same problem before, and the answer was that I've simply forgotten to call:

[self.locationManager startMonitoringForRegion:beaconRegion];

I assumed wrongly at first that if you start ranging with:

[self.locationManager startRangingBeaconsInRegion:beaconRegion];

... and getting data for rssi, accuracy and UUID in locationManager:didRangeBeacons:inRegion: method, the CLLocationManager should be able to figure out that the phone was in that region, but apparently not. So when asking for state, with:

[self.locationManager requestStateForRegion:beaconRegion];

I got CLRegionStateUnknown for that region in the locationManager:didDetermineState:forRegion: like you did.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top