I am using a custom BeaconManager delegate so that beacon ranging is not determined by the life-cycle of the view controller. Everything works great but every once in a while (1-2 days) beacon ranging will stop working and didRangeBeacons will never get called. The only way to fix this is for me to reset my iPhone, once I do this, it works perfectly. Below is the code that I am using. The basic flow is that when my ViewController calls ViewDidLoad it sends a notification back to the AppDelegate to tell it to start ranging for beacons, I never tell it to stop then because I want it to continue to range for beacons no matter where the user navigates to in the app. I'm wondering if my code is causing this or if this is just a bug with Bluetooth. Thanks for your help!
BeaconManager.m
#import "BeaconManager.h"
#import "AppDelegate.h"
@interface BeaconManager()<CLLocationManagerDelegate>
@property (nonatomic, strong) CLLocationManager *locationManager;
@property (nonatomic, strong) CLBeaconRegion *beaconRegion;
@end
@implementation BeaconManager
+ (id)sharedManager
{
static BeaconManager *sharedBeaconManager = nil;
static dispatch_once_t once;
dispatch_once(&once, ^{
sharedBeaconManager = [[self alloc] init];
});
return sharedBeaconManager;
}
- (id)init
{
self = [super init];
if(self)
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
}
return self;
}
- (void)startBeaconMonitoring:(NSString*)forUUID
{
NSUUID * uuid = [[NSUUID alloc] initWithUUIDString:forUUID];
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"com.beacons.publicRegion"];
[self.locationManager startMonitoringForRegion:self.beaconRegion];
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
- (void)stopBeaconMonitoring
{
//Stop the region monitoring
if(self.locationManager != nil && self.beaconRegion != nil) {
[self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
}
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
self.beacons = beacons;
if(self.delegate != nil) {
[self.delegate beaconManager:self didRangeBeacons:self.beacons];
}
}
@end
ViewController.m
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] postNotificationName:@"startRanging" object:nil userInfo:nil];
}
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startRangingForZombies) name:@"startRanging" object: nil];
return YES;
}
- (void)startRanging
{
//Start the beacon region monitoring when the controller loads
BeaconManager *beaconManager = [BeaconManager sharedManager];
beaconManager.delegate = self;
[beaconManager startBeaconMonitoring:@"1234-54324-34242-34242-43243"];
}