0


i was wondering why I don't get the notification if my beacon proximity is Immediate – when the app is in background. In foreground mode, everything works fine.

#import "ESTViewController.h"
#import <ESTBeaconManager.h>

@interface ESTViewController () <ESTBeaconManagerDelegate>

@property (nonatomic, strong) ESTBeaconManager* beaconManager;
@property (nonatomic, strong) ESTBeacon* selectedBeacon;
@property (weak, nonatomic) IBOutlet UILabel *outputLabel;

@end

@implementation ESTViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    /////////////////////////////////////////////////////////////
    // setup Estimote beacon manager

    // craete manager instance
    self.beaconManager = [[ESTBeaconManager alloc] init];
    self.beaconManager.delegate = self;
    self.beaconManager.avoidUnknownStateBeacons = YES;

    // create sample region with major value defined
    ESTBeaconRegion* region = [[ESTBeaconRegion alloc] initWithProximityUUID:ESTIMOTE_PROXIMITY_UUID identifier: @"EstimoteSampleRegion" ];

    NSLog(@"TODO: Update the ESTBeaconRegion with your major / minor number and enable background app refresh in the Settings on your device for the NotificationDemo to work correctly.");

    // start looking for estimote beacons in region
    [self.beaconManager startMonitoringForRegion:region];
    [self.beaconManager startRangingBeaconsInRegion:region];

    [self.beaconManager requestStateForRegion:region];

    // setup view
    self.outputLabel.text = @"Seachring for reagion";

}

-(void)beaconManager:(ESTBeaconManager *)manager
   didDetermineState:(CLRegionState)state
           forRegion:(ESTBeaconRegion *)region
{

    // NSLog(@"Region: %@", region);

    if(state == CLRegionStateInside)
    {
        NSLog(@"State: CLRegionStateInside");

    }
    else
    {
        NSLog(@"State: CLRegionOutside");
    }
}

-(void)beaconManager:(ESTBeaconManager *)manager
     didRangeBeacons:(NSArray *)beacons
            inRegion:(ESTBeaconRegion *)region
{
    if([beacons count] > 0)
    {

        self.selectedBeacon = [beacons firstObject]; // get the closest


        NSString* labelText = [NSString stringWithFormat:
                               @"Major: %i, Minor: %i\nRegion: ",
                               [self.selectedBeacon.major unsignedShortValue],
                               [self.selectedBeacon.minor unsignedShortValue]];

        // calculate and set new y position
        switch (self.selectedBeacon.proximity)
        {
            case CLProximityUnknown:
                labelText = [labelText stringByAppendingString: @"Unknown"];
                break;
            case CLProximityImmediate:
                labelText = [labelText stringByAppendingString: @"Immediate"];

                [self fireNotification];

                break;
            case CLProximityNear:
                labelText = [labelText stringByAppendingString: @"Near"];
                break;
            case CLProximityFar:
                labelText = [labelText stringByAppendingString: @"Far"];
                break;

            default:
                break;
        }

        self.outputLabel.text = labelText;
    }
}


-(void)fireNotification {
    NSLog(@"Fire Notification from background");

    // present local notification
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.alertBody = @"You are very close to the beacon";
    notification.soundName = UILocalNotificationDefaultSoundName;

    [[UIApplication sharedApplication] presentLocalNotificationNow:notification];

    // Request a server...
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
fabian
  • 5,433
  • 10
  • 61
  • 92

1 Answers1

4

With iOS, ranging for iBeacons generally only works in the foreground. The code that checks for CLProximityImmediate is in a ranging callback method.

If your app is in the background, it will only receive ranging callbacks for five seconds after entering/exiting a monitored iBeacon region.

This principle is true for the standard iOS CoreLocation APIs. While you are using the proprietary Estimote SDK, the same limitations also apply since it is a wrapper around the standard APIs.

davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • Any idea how to set the radius of a region? – fabian Jan 29 '14 at 18:51
  • You can't set the radius of a CLBeaconRegion or ESTBeaconRegion. The radius the physical transmitting range of the iBeacon, which is typically 50 meters, but can vary depending on the iBeacon hardware and obstacles or reflective radio surfaces in the area. Some iBeacons like my company's RadBeacon allow you to configure the transmitting power on the beacon itself. See http://www.radiusnetworks.com/radbeacon/ You can use RadBeacons with Estimote's proprietary SDK, with standard iOS APIs, and with our ProximityKit API as well. http://proximitykit.com – davidgyoung Jan 29 '14 at 19:29
  • what do you mean with "If your app is in the background, it will only receive ranging callbacks for five seconds after entering/exiting a monitored iBeacon region." So I will get notified if i leave the region in the background but the callback is called only for 5 seconds ? – Ilker Baltaci Nov 13 '14 at 13:56
  • After you get one region entry/exit callback, you will get ranging callbacks every second for 5-10 secs in the background if you have ranging enabled. But you can extend this time. See here: http://developer.radiusnetworks.com/2014/11/13/extending-background-ranging-on-ios.html – davidgyoung Nov 13 '14 at 17:57