Monitoring overlapping regions - ios

I use region monitoring in ios 6 and 7. It works fine, if regions are not overlapping. But if some regions are overlapping then the app calls delegate method didEnterRegion only for one region.
My code:
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
for (XPLocationModel* locationModel in models) {
if ([self.locationManager respondsToSelector:#selector(startMonitoringForRegion:)]) {
[self.locationManager startMonitoringForRegion:locationModel.region];
} else if ([self.locationManager respondsToSelector:#selector(startMonitoringForRegion:desiredAccuracy:)]) {
[self.locationManager startMonitoringForRegion:locationModel.region desiredAccuracy:XPGeofenceMaster_DesiredAccuracy];
}
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(#"%s id == %#", __PRETTY_FUNCTION__, region.identifier);
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
NSLog(#"%s", __PRETTY_FUNCTION__);
}

If you want, you can use the requestStateForRegion: method to get an update about all of your states, something like this. However, you better be prepared for enter and exit to be called multiple times.
- (void)requestStateForAllLocations
{
for (CLRegion *region in self.locationManager.monitoredRegions) {
[self.locationManager requestStateForRegion:region];
}
}

Related

didRangeBeacons call back always triggered with empty array of beacon

I'm using core location library in iOS for finding beacons, I'm in beacon region and the didRangeBeacons callback is triggering but it is always returning an empty array of beacons.
Please find the attached sample code. I have beacon immediate to iPhone, but still, beacon region state is inside when app opened and immediately it is changed to outside state and we are getting an empty array in didRangeBeacons. I have included both NSLocationWhenInUseUsageDescription. The NSLocationAlwaysUsageDescription keys are in the info.plist. The application has location permission set to "always". I'm using both Estimote and Kontakt beacons. OS version is iOS 11.2.6, Device iPhone 5s, Xcode 9.2.
#import "CoreLocationViewController.h"
#interface CoreLocationViewController ()
{
CLLocationManager *locationManager;
CLBeaconRegion *beacon_region;
}
#end
#implementation CoreLocationViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"CoreLocationViewController viewDidLoad");
NSUUID *ProximityUUID = [[NSUUID alloc] initWithUUIDString:#"b94f62c8-1af4-11e8-accf-0ed5f89f718b"];
beacon_region = [[CLBeaconRegion alloc] initWithProximityUUID:ProximityUUID identifier:#"abqwercds"];
[beacon_region setNotifyEntryStateOnDisplay:YES];
[beacon_region setNotifyOnExit:YES];
[beacon_region setNotifyOnEntry:YES];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
if ([CLLocationManager locationServicesEnabled]){
NSLog(#"Location Services Enabled");
if(IS_OS_8_OR_LATER){
NSLog(#"We are in LocationServicesRequestViewController IS_OS_8_OR_LATER");
NSUInteger code = [CLLocationManager authorizationStatus];
NSLog(#"CLLocationManager authorizationStatus %lu",(unsigned long)code);
if (code == kCLAuthorizationStatusNotDetermined) {
NSLog(#"kCLAuthorizationStatusNotDetermined");
[locationManager requestAlwaysAuthorization];
}
}else{
NSLog(#"We are in LocationServicesRequestViewController IS_OS_8_BELOW");
}
}else{
NSLog(#"authorizationStatus ");
}
}
#pragma mark Location Manager Delegate methods
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error{
NSLog(#"locationManager Error %#",error);
}
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
NSLog(#"Status of location service is %d",status);
if ((status == kCLAuthorizationStatusAuthorizedAlways) || (status == kCLAuthorizationStatusAuthorizedWhenInUse)){
NSLog(#"location service status changed 1");
[locationManager startMonitoringForRegion:beacon_region];
[locationManager requestStateForRegion:beacon_region];
}else{
NSLog(#"location service status changed 2");
}
}
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{
NSLog(#"CLLocationManager Beacon Region State Determine ");
switch (state) {
case CLRegionStateUnknown:
{
NSLog(#" CLLocationManager Region state is unknown %#",region);
[locationManager stopMonitoringForRegion:beacon_region];
break;
}
case CLRegionStateInside:
{
NSLog(#" CLLocationManager Region state is In-Side %#",region);
[locationManager startRangingBeaconsInRegion:beacon_region];
}
case CLRegionStateOutside:
{
NSLog(#" CLLocationManager Region state is Out-Side %#",beacon_region);
[locationManager stopMonitoringForRegion:beacon_region];
break;
}
}
}
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
NSLog(#" CLLocationManager Enter into Region %#",region);
[locationManager startRangingBeaconsInRegion:beacon_region];
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
NSLog(#"didExitRegion location manager %#",region );
[locationManager stopMonitoringForRegion:beacon_region];
}
-(void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region{
NSLog(#"CLLocationManager Beacon Monitoring Started for the region %#",region);
}
-(void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error{
NSLog(#"CLLocationManager Monitoring of beacon region %# is failed, Error %#",region,error);
}
-(void)locationManager:(CLLocationManager *)manager rangingBeaconsDidFailForRegion:(CLBeaconRegion *)region withError:(NSError *)error{
NSLog(#"CLLocationManager ranging of beacon region %# is failed, Error %#",region.proximityUUID,error);
}
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray<CLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region{
NSLog(#"beacons %#",beacons);
}

How to stop iBeacon scanning

i tried with this Code but this delegates are not calling and not stoping the scanning, at one particular condition i need to call some other function.
-(void)locationManager:(CLLocationManager *)manager stopRangingBeaconsInRegion:(CLBeaconRegion *)region
{
NSLog(#"STOP PLEASEEEEEEEE");
}
- (void)locationManager:(CLLocationManager *)manager stopMonitoringForRegion:(CLRegion *)region {
NSLog(#"didExitRegion");
[manager stopRangingBeaconsInRegion:(CLBeaconRegion*)region];
NSLog(#"StopRangingBeacons");
}
am using this code to start the beaconScanning
-(void)loadUIElements
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND , 0), ^{
self.beaconRegionAny = [[AIBBeaconRegionAny alloc] initWithIdentifier:#"Any"];
[self.locationManager requestWhenInUseAuthorization];
self.locationManager.pausesLocationUpdatesAutomatically = YES;
[self.locationManager startRangingBeaconsInRegion:self.beaconRegionAny]; });
}
calling this function when start monitoring the beacons
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
You have to remove the listener from your monitoredRegions list using stopMonitoring(for:). Here'a a link to the documentation
Have you tried this?
[self.locationManager stopMonitoringForRegion:self.beaconRegionAny];
create a button action and this line of code.
#IBAction func launchButtonClicked(_ sender: Any) {
// Determine action based on button state
switch (launchButton.currentState) {
case .Start:
beaconManager.startRangingBeacons(in: region)
launchButton.currentState = .Stop
case .Stop:
beaconManager.stopRangingBeacons(in: region)
launchButton.currentState = .Start
}
}
Try this way, it works

locationManager didExitRegion or locationManager didEnterRegion never called

- (void)viewDidLoad
{
[super viewDidLoad];
if([CLLocationManager locationServicesEnabled]){
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
CLLocationCoordinate2D companyCenter;
companyCenter.latitude = 23.126272;
companyCenter.longitude = 113.395568;
CLRegion* fkit = [[CLCircularRegion alloc] initWithCenter:companyCenter
radius:500 identifier:#"fkit"];
[self.locationManager startMonitoringForRegion:fkit];
}else{
NSLog(#"not support");
}
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(#"Error : %#",error);
}
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
{
NSLog(#"Region monitoring failed with error: %#", [error localizedDescription]);
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(nonnull CLRegion *)region
{
NSLog(#"Entered Region - %#", region.identifier);
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(nonnull CLRegion *)region
{
NSLog(#"Entered Enter Region - %#", region.identifier);
}
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
NSLog(#"Started monitoring %# region", region.identifier);
}
Above is my code. I run in simulator without location,and then set custome location(23.126272,113.395568) in Debug ->location item , and it never call didEnterRegion delegate . anyone can help me ?
PS:my Xcode is 7.1.1, and Console log "Started monitoring fkit region"
You are missing a few steps. You have to add an entry to your info.plist declaring that you want to use location services while your app is in the foreground, (Using the NSLocationWhenInUseUsageDescription key) and then you need to check to see if you have permission, and ask for it if you don't.
Do a search on the string "Requesting Permission to Use Location Services" in the Xcode docs for more information.
Add this line in didStartMonitoringForRegion
[self.locationManager requestStateForRegion:yourregion];

Why beacons cause Bluetooth to continuously toggle?

I am experiencing a really weird bug working with iOS and iBeacon. I have a really simple BeaconManager that ranges beacons with particular UUID, major and minor values and performs some actions once it found them. My app seems to work properly until it continuously toggle the Bluetooth status and stop doing its job. The only visible result is that the Bluetooth icon in the status bar start flickering due to Bluetooth stopping and restarting.
Where to focus attention?
This is my class definition:
#import "BeaconManager.h"
#implementation BeaconManager
- (instancetype)init {
self = [super init];
if (self) {
NSURL *beep = [[NSBundle mainBundle] URLForResource:#"beep" withExtension:#"aiff"];
soundFileURLRef = (CFURLRef) CFBridgingRetain(beep);
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundFileObject);
// Initializes properties
beacon = [CLBeacon new];
foundBeacons = [NSMutableArray new];
_lastBeaconActionTimes = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void)initRegion {
// Initializes the beacon region by giving it an UUID and an identifier
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:BEACON];
beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:#"beacon.region"];
// Starts looking for beacon within the region
[self.locationManager startMonitoringForRegion:beaconRegion];
}
- (void)checkBeacon {
if (!self.locationManager) {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
[self.locationManager requestWhenInUseAuthorization];
}
[self initRegion];
[self locationManager:self.locationManager didStartMonitoringForRegion:beaconRegion];
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
[self.locationManager startMonitoringForRegion:beaconRegion];
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
[self.locationManager stopRangingBeaconsInRegion:beaconRegion];
}
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error {
NSLog(#"Failed monitoring region: %#", error);
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(#"Location manager failed: %#", error);
}
- (void)locationManager:(CLLocationManager *)manager
didRangeBeacons:(NSArray *)beacons
inRegion:(CLBeaconRegion *)region {
if (foundBeacons.count == 0) {
for (CLBeacon *filterBeacon in beacons) {
// If a beacon is located near the device and its major value is equal to 1000 (MAJOR constant)
if (((filterBeacon.proximity == CLProximityImmediate) || (filterBeacon.proximity == CLProximityNear)))
// Registers the beacon to the list of found beacons
[foundBeacons addObject:filterBeacon];
}
}
// Did some beacon get found?
if (foundBeacons.count > 0) {
// Takes first beacon of the list
beacon = [foundBeacons firstObject];
if (([beacon.major isEqualToNumber:[NSNumber numberWithInt:MAJOR]]) && ([beacon.minor isEqualToNumber:[NSNumber numberWithInt:MINOR]])) {
// Takes the actual date and time
NSDate *now = [[NSDate alloc] init];
NSString *key = [NSString stringWithFormat:#"%# %# %#", [beacon.proximityUUID UUIDString], beacon.major, beacon.minor];
NSDate *lastBeaconActionTime = [_lastBeaconActionTimes objectForKey:key];
if ((lastBeaconActionTime == nil) || ([now timeIntervalSinceDate:lastBeaconActionTime] > MINIMUM_ACTION_INTERVAL_SECONDS)) {
[_lastBeaconActionTimes setObject:now forKey:key];
// Plays beep sound
AudioServicesPlaySystemSound(soundFileObject);
if (self.delegate) {
// Performs actions related to the beacon (i.e. delivers a coupon)
[self.delegate didFoundBeacon:self];
}
self.locationManager = nil;
}
// else [self.locationManager stopMonitoringForRegion:region];
}
[foundBeacons removeObjectAtIndex:0];
beacon = nil;
}
}
#end
Can't say for sure this is the reason why Bluetooth keeps toggling, but this part is definitely suspicious:
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
[self.locationManager startMonitoringForRegion:beaconRegion];
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
}
This is essentially an infinite loop. Once monitoring starts, iOS invokes the didStartMonitoring method … which starts monitoring for the very same region, which makes the iOS invoke the didStartMonitoring method again, which …
I'd start with removing the startMonitoringForRegion line from this part of your code.

Location Updates Not working in iPhone 5 (iOS 7) but working in simulator

I was having problem with background location services in my iPhone. So, I decided to test foreground services on my device. The best thing was that even it didn't work.
- (IBAction) btnPressed
{
[self startStandardUpdates]
}
- (void)startStandardUpdates
{
if (nil == self.manager) {
[CLLocationManager locationServicesEnabled];
self.manager = [[CLLocationManager alloc] init];
self.manager.delegate = self;
self.manager.desiredAccuracy = kCLLocationAccuracyBest;
self.manager.pausesLocationUpdatesAutomatically = NO;
[self.manager startUpdatingLocation];
}
}
- (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager
{
NSLog(#"Paused");
}
- (void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager
{
NSLog(#"Resumed");
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"Error : %#", error);
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(#"Locations : %#",locations);
}
After showing three updates it stops. And - (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager is never called as "Paused" is never logged out.
Is the device sitting stationary? If so I think Core Location stops firing based on your desired accuracy once it determines the device has not moved beyond the specified radius. No need to right.

Resources