Summary: For installations with regular beacons (an iBeacon is a type of beacon) then you cannot do much without an app, as you cannot interact with users (even after the additions from Eddystone).
An iBeacon is a device that emits a Bluetooth signal that can be detected by your devices. Companies can deploy iBeacon devices in environments where proximity detection is a benefit to users, and apps can use the proximity of beacons to determine an appropriate course of action.
1 Answer. Show activity on this post. The quick answer is that iBeacons use bluetooth low energy, so simply turning off bluetooth will opt you out of tracking as well as notifications.
How iBeacon works. The beacon's job is to continuously scan for smartphones and tablets that have Bluetooth open and are running the beacon's compatible mobile app. When such a device comes within range, the beacon sends a connection request to wake up the app.
Yes, it's possible and should be automatic.
After you have created a CLBeaconRegion and started monitoring on it, Location Services will keep track of whether your phone is in or out of the region, even when your app isn't running. If you app isn't running during a transition, iOS will launch your app into the background for a few seconds to call the appropriate CLLocationManagerDelegate methods.
I found out the above behavior through experimentation with my own app, but have also witnessed it with Apple's AirLocate sample program. With AirLocate, if you set up a monitoring region then reboot your phone, AirLocate will still deliver a local notification as soon as the phone enters the region.
Take care when testing this, because sometimes it takes up to 4 minutes after turning on/off an iBeacon before iOS recognizes the region state transition. EDIT: As of the iPhone 5, apps will typically use hardware acceleration to detect beacons within a few seconds, and if hardware acceleration is not available, it can take up to 15 minutes.
EDIT 3: AS of iOS 13, you must make sure the user actually grants background permission and not "only once" or "when in use" permission which are heavily pushed by the operating system in the dialogs they present to the user. See here for details.
EDIT 2: As of iOS 8, you need to make sure you have called and successfully obtained locationManager.requestAlwaysAuthorization()
as locationManager.requestWhenInUseAuthorization()
only lets beacons be detected in the foreground.
I have posted a detailed discussion on how this all works in this blog post.
OK I've gotten this to work correctly and experimented around with it so here is the answer. This is what you need to do to get your app to be invoked when crossing a beacon region boundary after the app has been terminated (assuming your app works properly when in the foreground):
CLLocation
delegate inside your AppDelegate.m
module. This delegate is what gets invoked by iOS 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. This is what Apple's AirLocate sample app does.So, inside AppDelegate.m
you need the following (you also need to link in CoreLocation.h
):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// This location manager will be used to notify the user of region state transitions when the app has been previously terminated.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
return YES;
}
Inside AppDelegate.m
, you need to implement the locationManager didDetermineState method, like this:
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{
UILocalNotification *notification = [[UILocalNotification alloc] init];
if(state == CLRegionStateInside)
{
notification.alertBody = [NSString stringWithFormat:@"You are inside region %@", region.identifier];
}
else if(state == CLRegionStateOutside)
{
notification.alertBody = [NSString stringWithFormat:@"You are outside region %@", region.identifier];
}
else
{
return;
}
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
--> So if your app has been terminated (it must be run at least ONCE), when the device transitions across a beacon boundary that you are monitoring, iOS will invoke your app and call the locationManager:didDetermineState
method in your AppDelegate.m module. Inside this method you can then set up and call presentLocalNotificationNow. If your app is NOT in the foreground when this happens, iOS will present the notification on the screen even if it is locked. The user will then have to invoke the app for more information.
I'm pretty sure that memory pressure has nothing to do with this. Also, the setting notifyEntryStateOnDisplay
has nothing to do this this issue either. Setting notifyEntryStateOnDisplay
is only used when the user turns on the iOS device display (ie hits "home" or top left button). If the user does this and notifyEntryStateOnDisplay
is TRUE
, AND the device is INSIDE the beacon region you are monitoring for, THEN you get a notification on the display at that time. If this property is set to FALSE
, you don't.
Of course, you need to be running iOS 7.1 in order for this stuff to work correctly.
For more details, visit Apple's documentation
You need to switch notifyEntryStateOnDisplay=YES for CLBeaconRegion for the system to wake your app for iBeacon entry/exit event.
But there is one tricky part. If your app is not running the system will only wake your app for beacon entry/exit handling if your app was terminated previously due to system memory pressure. If the user kills the app by swiping it up in the task view, the system will not wake your app. To verify this behaviour, launch you app, put it to background, then consecutively launch several memory consuming apps. I launched several 3D games before my app gets terminated by the system due to memory pressure.
Just upgrade your iOS version to 7.1 and set "notifyEntryStateOnDisplay=YES" and it should work like a charm even when your app is not running. I was having this problem earlier but it got fixed once I did this upgrade! Enjoy..
The only way I have been able to make this work is by monitoring for major location changes which seem to do the trick. Be warned I have not tested this for all of the device or use case scenarios.
Yes, we can present the local notification in kill state or in the background state, just follow the steps,
1) Start location manager using CLLocationManager class.
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy=kCLLocationAccuracyBest;
locationManager.distanceFilter=kCLDistanceFilterNone;
2) Create CLBeaconRegion like,
CLBeaconRegion *beacon_Region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid major:mjorVa minor:minorVa identifier:identifier];
beacon_Region.notifyEntryStateOnDisplay = YES;
beacon_Region.notifyOnEntry=YES;
beacon_Region.notifyOnExit=YES;
3) Implement two location manager delegate method like,
-didEnterRegion
-didExitRegion
The above two location manager method will work even your app is kill or in background. The system will keep track of your beacon and when it goes out of the range the system will fire the didExitRegion method and when comes in the system will fire the didEnterRegion method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With