iBeacon region monitoring in Background.

22:06

See also Ranging and Monitoring

iBeacon : Whether region monitoring possible even after the application killed from Background ?

Yes, this is the OS level notification. To get this event in your application you must implement a CLLocation delegate inside your AppDelegate.m module. This delegate is what gets invoked by OS so if you don't have the CLLocation delegate code in AppDelegate.m, you won't be able to respond to iOS when your app has been terminated.

 - (void) startRangingForRegion:(CLBeaconRegion*) beaconRegion  
 {  
   if (![CLLocationManager isRangingAvailable]) return;  
   //If a ranging going on already for this beaconRegion, end it .  
   NSNumber * bgTaskNumber = [_backgroundTasks objectForKey:beaconRegion.proximityUUID.UUIDString];  
   if (bgTaskNumber) {  
     [self endRangingForRegion:beaconRegion];  
   }  
   //Starting a new background task to Range this beaconRegion  
   UIApplication *application = [UIApplication sharedApplication];  
   UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{  
     //This block will be triggered when the background task forcefully stopped by the OS  
     //Do any emergency action before the final quit.  
     [self endRangingForRegion:beaconRegion];  
   }];  
   //Keep this background task in the dictionary _backgroundTasks  
   bgTaskNumber = [NSNumber numberWithUnsignedInteger:bgTask];  
   [_backgroundTasks setObject:bgTaskNumber forKey:beaconRegion.proximityUUID.UUIDString];  
   //Start the Ranging for the new beaconRegion  
   if (beaconRegion) {  
     [_locationManager startRangingBeaconsInRegion:beaconRegion];  
   }  
   //The ranging will get time untill endBackgroundTask is called.  
 }  

 -(void) endRangingForRegion:(CLBeaconRegion*) beaconRegion  
 {  
   if (![CLLocationManager isRangingAvailable]) return;  
   if (beaconRegion) {  
     //Stop Ranging the Beacon Region  
     [_locationManager stopRangingBeaconsInRegion:beaconRegion];  
     NSNumber * bgTaskNumber = [_backgroundTasks objectForKey:beaconRegion.proximityUUID.UUIDString];  
     //Take out the corresponding background task from the dictionary  
     UIBackgroundTaskIdentifier bgTask = [bgTaskNumber unsignedIntegerValue];  
     if (bgTaskNumber && bgTask != UIBackgroundTaskInvalid) {  
       //Ending the background task corresponding to the region  
       [[UIApplication sharedApplication] endBackgroundTask:bgTask];  
       //Remove the task from the dictionary _backgroundTasks  
       [_backgroundTasks removeObjectForKey:beaconRegion.proximityUUID.UUIDString];  
     }  
   }  
 }  


Also the didReceiveLocalNotification is implemented to show the notification as an alert when the application is running in foreground.

Forcefully trigger region cross event

requestStateForRegion

Getting optimal Ranging when the application is in background/killed.

Suppose you entered to the vicinity of a beacon region in the proximity ‘far’, you want to notify user when he is in ‘near’ or ‘immediate proximity. In this case if the application is in foreground you can simply start region ranging once the device entered the region. The possible workaround for the application running in background is given below,

Start ranging for the detected region and find the more closer beacon and notify “You are nearing to … “ that particular beacon , and when the user tapping on the notification the application will come to foreground so that the ranging will work like anything, when the user reached in the expected proximity notify “Welcome to the region.”

We can even extend the ranging for a maximum of 10 minutes by starting ranging after beginBackgroundTaskWithExpirationHandler method is called.


 - (void) startRangingForRegion:(CLBeaconRegion*) beaconRegion  
 {  
   if (![CLLocationManager isRangingAvailable]) return;  
   //If a ranging going on already for this beaconRegion, end it .  
   NSNumber * bgTaskNumber = [_backgroundTasks objectForKey:beaconRegion.proximityUUID.UUIDString];  
   if (bgTaskNumber) {  
     [self endRangingForRegion:beaconRegion];  
   }  
   //Starting a new background task to Range this beaconRegion  
   UIApplication *application = [UIApplication sharedApplication];  
   UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{  
     //This block will be triggered when the background task forcefully stopped by the OS  
     //Do any emergency action before the final quit.  
     [self endRangingForRegion:beaconRegion];  
   }];  
   //Keep this background task in the dictionary _backgroundTasks  
   bgTaskNumber = [NSNumber numberWithUnsignedInteger:bgTask];  
   [_backgroundTasks setObject:bgTaskNumber forKey:beaconRegion.proximityUUID.UUIDString];  
   //Start the Ranging for the new beaconRegion  
   if (beaconRegion) {  
     [_locationManager startRangingBeaconsInRegion:beaconRegion];  
   }  
   //The ranging will get time untill endBackgroundTask is called.  
 }  

 -(void) endRangingForRegion:(CLBeaconRegion*) beaconRegion  
 {  
   if (![CLLocationManager isRangingAvailable]) return;  
   if (beaconRegion) {  
     //Stop Ranging the Beacon Region  
     [_locationManager stopRangingBeaconsInRegion:beaconRegion];  
     NSNumber * bgTaskNumber = [_backgroundTasks objectForKey:beaconRegion.proximityUUID.UUIDString];  
     //Take out the corresponding background task from the dictionary  
     UIBackgroundTaskIdentifier bgTask = [bgTaskNumber unsignedIntegerValue];  
     if (bgTaskNumber && bgTask != UIBackgroundTaskInvalid) {  
       //Ending the background task corresponding to the region  
       [[UIApplication sharedApplication] endBackgroundTask:bgTask];  
       //Remove the task from the dictionary _backgroundTasks  
       [_backgroundTasks removeObjectForKey:beaconRegion.proximityUUID.UUIDString];  
     }  
   }  
 }  

The startRangingForRegion: should be called when a particular region is entered, and the endRangingForRegion: method should be called when the region is exited.

NotifyEntryStateOnDisplay any Importance ?

This property is not related to the normal background support , but to get call in locationManager:didDetermineState:forRegion: delegate method when the user turns on the iOS device display (ie hits "home" or top left button). 

When set to YES, the location manager sends beacon notifications when the user turns on the display and the device is already inside the region. These notifications are sent even if your app is not running. In that situation, the system launches your app into the background so that it can handle the notifications. In both situations, the location manager calls the locationManager:didDetermineState:forRegion: method of its delegate object.

The default value for this property is NO.

You Might Also Like

0 comments

Popular Posts

Like us on Facebook

Flickr Images