Receive iBeacons notifications in every two minutes while in the range

I’m really really new to this iBeacon thing. I was able to create a sample app to receive notifications from iBeacons and it is working fine. What I need to know is, can we send notifications according to a defined time (e.g. 2 minutes) for a particular iBeacon while the device is in that Beacon region? If so how can we do that?

At the moment I’m receiving notifications only when the device enter to the Beacon region and exit from the Beacon region. How I test the exit scenario is removing the battery from the Beacon.

I’m testing with this iPhone 5S (iOS version 9.3)

Thanks

In your “didEnter” event, you can schedule the notification to happen not immediately, but two minutes from now. And in case the user leaves the region before the notification is shown, you can cancel it in “didExit”.

Code snippet here:

var notification: UILocalNotification?

func beaconManager(manager: AnyObject, didEnterRegion region: CLBeaconRegion) {
    self.notification = UILocalNotification()
    notification.alertBody = "Hello, world!"
    notification.fireDate = NSDate(timeIntervalSinceNow: 120)
    UIApplication.sharedApplication().scheduleLocalNotification(self.notification)
}

func beaconManager(manager: AnyObject, didExitRegion region: CLBeaconRegion) {
    UIApplication.sharedApplication().cancelLocalNotification(self.notification)
}

@heypiotr thanks for the reply but the solution given by you is nothing to do with Beacons related coding, it is a way of delaying local notifications.

Another point is, what I have asked is getting notified in every 2 minutes while the device is in the Beacon range. As you suggest, your solution is valid only the device is exit from the region and enter back to the region only.

I found some different solution while digging in to the Estimote documentations. That is,

self.utilityManager.startEstimoteBeaconDiscoveryWithUpdateInterval(120)

and it will call the ESTUtilityManagerDelegate method

func utilityManager(manager: ESTUtilityManager, didDiscoverBeacons beacons: [ESTDevice])

in every 2 minutes as I expected. But it has one issue, that is, I cannot identify which Beacon call that method.

If I clarify more, I am monitoring two regions with only difference with minor value.

self.beaconManager.startMonitoringForRegion(CLBeaconRegion(proximityUUID: NSUUID(UUIDString: "ABC")!, major: 1, minor: 2, identifier: "monitored region"))

self.beaconManager.startMonitoringForRegion(CLBeaconRegion(proximityUUID: NSUUID(UUIDString: "ABC")!, major: 1, minor: 4, identifier: "monitored region"))

Is there any way I can identify those two Beacons separately inside didDiscoverBeacons function ?

Yes, it doesn’t have anything to do with iBeacon, because what you’re trying to do is not iBeacon-specific at all (: iOS apps usually go to “suspended” state as soon as the user locks the phone or leaves the app, and there’s no way to make it “wake up” at a given point in time, or on a recurring schedule. Ask people that have been trying to implement 3rd party Alarm apps—they’re using scheduled local notifications as well.

The “utility manager method” is somewhat of a workaround: with the “uses Bluetooth accessories” Background Mode enabled, iOS will prevent the app from being “suspended” and instead will keep it running in the background as long as you remain in range of a Bluetooth device that the app is scanning for—in case of the Utility Manager, that’ll be all the Estimote Beacons. This means that you can even use the regular NSTimer with “repeat” set to YES, and it should still work. Some things to keep in mind with this method though:

  1. Apple is very strict about apps using the Background Modes, you’ll likely need to explain during the App Review why your app is doing that … and saying “to keep it running in the background as long as it’s in range of beacons, so that I can fire notifications every 2 minutes” might or might not fly.
  2. The app will prevent the phone from going to sleep in range of the beacon, which will contribute to excess battery drain, which in turn might result in the user uninstalling your app. I’d conduct some battery-usage tests before I’d go that route.
  3. In the documentation of the background execution, Apple says that apps that keep running in the background for extensive periods of time might be force-killed by iOS. I did some testing in the past and I observed just that, although I’m not sure if that was simply some bug in Core Bluetooth, or did iOS really kill my app because I left it running in range of a beacon overnight.

And so to your specific question, “Is there any way I can identify those two Beacons separately inside didDiscoverBeacons function”, you can use the identifier property of ESTDevice for that. It’s the same “identifier” that shows up on cloud.estimote.com, on the beacon list, below the beacon’s name.