I have three brand new Kontakt.io beacons and used this tutorial and its source to try and identify them with my iPhone 4s. All I did is change the UUID (all Kontakt.io beacons had the same UUID fromt the start) and add some code:
This line is supposed to force the app to check also if it's already IN the region
[self.locationManager requestStateForRegion:self.myBeaconRegion];
These lines are supposed to check if the system is set up in the correct way:
NSArray *locationServicesAuthStatuses = @[@"Not determined",@"Restricted",@"Denied",@"Authorized"];
NSArray *backgroundRefreshAuthStatuses = @[@"Restricted",@"Denied",@"Available"];
BOOL monitoringAvailable = [CLLocationManager isMonitoringAvailableForClass:[self.myBeaconRegion class]];
NSLog(@"Monitoring available: %@", [NSNumber numberWithBool:monitoringAvailable]);
int lsAuth = (int)[CLLocationManager authorizationStatus];
NSLog(@"Location services authorization status: %@", [locationServicesAuthStatuses objectAtIndex:lsAuth]);
int brAuth = (int)[[UIApplication sharedApplication] backgroundRefreshStatus];
NSLog(@"Background refresh authorization status: %@", [backgroundRefreshAuthStatuses objectAtIndex:brAuth]);
When I start the app, with the iBeacons next to my phone, didEnterRegion is not fired. Also when I take out the battery and put them back in (to simulate going out of the range and going back in), nothing happens. Other Github-example codes didn't work for me either when using real iBeacons, only when I use another iPhone to transmit the signals.
This is the ViewController.h:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Initialize location manager and set ourselves as the delegate
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// Create a NSUUID with the same UUID as the broadcasting beacon
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"A77A1B68-49A7-4DBF-914C-760D07FBB87B"];
// Setup a new region with that UUID and same identifier as the broadcasting beacon
self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
identifier:@"com.appcoda.testregion"];
// Tell location manager to start monitoring for the beacon region
[self.locationManager startMonitoringForRegion:self.myBeaconRegion];
// Force app to check if it's already IN the region
[self.locationManager requestStateForRegion:self.myBeaconRegion];
// Check if beacon monitoring is available for this device
if (![CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Monitoring not available" message:nil delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil]; [alert show]; return;
}
NSArray *locationServicesAuthStatuses = @[@"Not determined",@"Restricted",@"Denied",@"Authorized"];
NSArray *backgroundRefreshAuthStatuses = @[@"Restricted",@"Denied",@"Available"];
BOOL monitoringAvailable = [CLLocationManager isMonitoringAvailableForClass:[self.myBeaconRegion class]];
NSLog(@"Monitoring available: %@", [NSNumber numberWithBool:monitoringAvailable]);
int lsAuth = (int)[CLLocationManager authorizationStatus];
NSLog(@"Location services authorization status: %@", [locationServicesAuthStatuses objectAtIndex:lsAuth]);
int brAuth = (int)[[UIApplication sharedApplication] backgroundRefreshStatus];
NSLog(@"Background refresh authorization status: %@", [backgroundRefreshAuthStatuses objectAtIndex:brAuth]);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)locationManager:(CLLocationManager*)manager didEnterRegion:(CLRegion *)region
{
// We entered a region, now start looking for our target beacons!
self.statusLabel.text = @"Finding beacons.";
[self.locationManager startRangingBeaconsInRegion:self.myBeaconRegion];
}
-(void)locationManager:(CLLocationManager*)manager didExitRegion:(CLRegion *)region
{
// Exited the region
self.statusLabel.text = @"None found.";
[self.locationManager stopRangingBeaconsInRegion:self.myBeaconRegion];
}
-(void)locationManager:(CLLocationManager*)manager
didRangeBeacons:(NSArray*)beacons
inRegion:(CLBeaconRegion*)region
{
// Beacon found!
self.statusLabel.text = @"Beacon found!";
CLBeacon *foundBeacon = [beacons firstObject];
// You can retrieve the beacon data from its properties
//NSString *uuid = foundBeacon.proximityUUID.UUIDString;
//NSString *major = [NSString stringWithFormat:@"%@", foundBeacon.major];
//NSString *minor = [NSString stringWithFormat:@"%@", foundBeacon.minor];
}
This is the NSLog output:
2014-05-29 00:49:19.951 BeaconReceiver[2803:60b] Monitoring available: 1
2014-05-29 00:49:19.967 BeaconReceiver[2803:60b] Location services authorization status: Authorized
2014-05-29 00:49:20.109 BeaconReceiver[2803:60b] Background refresh authorization status: Available
Thanks a lot for your help!!
Firstly, verify you can detect your beacons with an off-the-shelf app like Locate for iBeacon available here: https://itunes.apple.com/us/app/locate-for-ibeacon/id738709014?mt=8. It will verify that the beacons are working properly and the UUIDs are configured to be what you expect.
Once you know for sure the beacons work with your device, then start troubleshooting your code.
EDIT: Also be sure to reboot your phone before testing to guard against a known iOS 7.1 bug;: https://stackoverflow.com/a/22949187/1461050