Ranging beacons after didEnterRegion is triggering

Hello,

I want to develop an iOS App with Swift capable of monitoring a specific region in backgroud. Specifically, if the didEnterRegion method in triggering I would like to ranging beacons during 10 seconds. It is described and mentioned many times, but I do not khow what is the correct structure of the AppDelegate file.

This is my file:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, ESTBeaconManagerDelegate {

    var window: UIWindow?
    
    let beaconManager = ESTBeaconManager()
    
    let beaconRegion = CLBeaconRegion(proximityUUID: NSUUID(UUIDString: "xxx")!, identifier: "myregion")


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        
        self.beaconManager.delegate = self
        self.beaconManager.requestAlwaysAuthorization()
        
        UIApplication.sharedApplication().registerUserNotificationSettings(
            UIUserNotificationSettings(forTypes: .Alert, categories: nil))
        
        self.beaconManager.startMonitoringForRegion(beaconRegion)
        self.beaconManager.requestStateForRegion(beaconRegion)
        return true
    }
    
    func beaconManager(manager: AnyObject, didDetermineState state: CLRegionState, forRegion region: CLBeaconRegion) {
        
        let notification = UILocalNotification()
        if (state == CLRegionState.Inside){
            notification.alertBody = "Inside"
        }
        else if (state == CLRegionState.Outside){
            notification.alertBody = "Outside"
        }
        else if (state == CLRegionState.Unknown){
            notification.alertBody = "Unknown"
        }
        UIApplication.sharedApplication().presentLocalNotificationNow(notification)
    }
    
    func beaconManager(manager: AnyObject, didEnterRegion region: CLBeaconRegion) {
        self.beaconManager.startRangingBeaconsInRegion(self.beaconRegion)
        let notification = UILocalNotification()
        notification.alertBody =
            "Alert String"
        UIApplication.sharedApplication().presentLocalNotificationNow(notification)
    }
    
    func beaconManager(manager: AnyObject, didRangeBeacons beacons: [CLBeacon],
                       inRegion region: CLBeaconRegion) {
        if let nearestBeacon = beacons.first {
            let notification = UILocalNotification()
            notification.alertBody =
                "\(nearestBeacon.proximityUUID.UUIDString), \(nearestBeacon.major), \(nearestBeacon.minor)"
            UIApplication.sharedApplication().presentLocalNotificationNow(notification)
        }
    }
    ...
}

Where could I call stopRangingBeaconsInRegion? Region monitoring should be stopped while ranging is used?

Could you provide me an example of how to prolongate the 10 seconds available time since a Google backend should be queried?

Thanks in advance.

Regards,

Juan Antonio

Here’s how to start a background task, to give your app more time in the background:

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/index.html#//apple_ref/occ/instm/UIApplication/beginBackgroundTaskWithExpirationHandler:

Thanks for your answer.

Could you provide me any feedback related to my questions?

“Where could I call stopRangingBeaconsInRegion? Region monitoring should be stopped while ranging is used?”

Regards,

Juan Antonio

Ranging will automatically pause when your app’s background time (~ 10 seconds without a background task, ~ 3 minutes with a background task) runs out, and resume the next time the app “wakes up”.

If you want to stop ranging for good, you can e.g. count to 5 calls of the “didRange” delegate, and then stop it.

Here`s a more understandable example in my opinion: http://developer.radiusnetworks.com/2014/11/13/extending-background-ranging-on-ios.html

Thanks. I read the article and it helps me too much.

Regards,

Juan Antonio

Hello.

I was trying to write the same example for Android, but in this case is not required. It was very simple since I can get the UUID + major + minor when enterRegion is triggering.

Is it ok or I should write an example with the same structure used in iOS??

Thanks and regards,

Juan Antonio

Yeah, on Android, that’s a bit easier indeed, as we fully control the BLE/iBeacon scanning (unlike on iOS) and thus can get you the exact major/minor of the beacon that triggered the enter event. So the simple implementation should work just fine.