Region can NOT be nil error

Hi,

After updating my Estimote iOS SDK from v. 2.1.5 to 2.2.1 I get an error when trying to range for beacons.

I declare my different beacon related objects between @interface and @end:
@property (nonatomic, strong) ESTBeaconManager* beaconManager;
@property (nonatomic, strong) ESTBeacon* selectedBeacon;
@property (nonatomic, strong) ESTBeaconRegion* beaconRegion;

In viewDidLoad:

self.beaconManager = [[ESTBeaconManager alloc] init];
self.beaconManager.delegate = self;

self.beaconRegion = [[ESTBeaconRegion alloc] initWithProximityUUID: self.selectedBeacon.proximityUUID major:[self.selectedBeacon.major unsignedShortValue] minor:[self.selectedBeacon.minor unsignedShortValue] identifier:@"myRgn"];

I then run:
[self.beaconManager startRangingBeaconsInRegion:self.beaconRegion];

and get the error below:
"Error Domain=com.estimote Code=438 "Region can NOT be nil" UserInfo=0x14d638c0 {NSLocalizedDescription=Region can NOT be nil}"

I reverted to SDK 2.1.5 and there the ranging starts and works as intended. What do I need to get it working with SDK 2.2.1?

Thanks in advance,
Max

Update:

After changing self.beaconRegion = [...]

to:

self.beaconRegion = [[ESTBeaconRegion alloc] initWithProximityUUID:ESTIMOTEPROXIMITYUUID
identifier:@"EstimoteSampleRegion"];

the ranging works. However, when trying to connect to a beacon the app is stuck connecting. I'm authorizing my app using
[ESTBeaconManager setupAppID:@"myAppID" andAppToken:@"myAppToken"]; so it should(?) be entitled to connect.

I noticed you've updated your SDK to v. 2.3.0. Maybe or maybe not my issue will be resolved if I update to that version. When will it be available through Cocoapods?

Cheers!

Some progress.

Instead of declaring my ESTBeacon object between @interface and @end, I now do it like this: ESTBeacon *myBeacon = [beacons firstObject] in

-(void)beaconManager:(ESTBeaconManager *)manager
didRangeBeacons:(NSArray *)beacons
inRegion:(ESTBeaconRegion *)region
{

I also set myBeacon.delegate = self before connecting to to it.

This lets me connect to a beacon that does NOT have secure UUID activated. I cannot, however, connect to one of my secure beacons.

Hey Max,

Can you double check that your beacon region is not nil? Starting with SDK 2.2, we added the non-nil region validation to ranging and monitoring. If you don't get the error on SDK 2.1.5, it might still mean that the region is nil, there's simply no check on the SDK's side for that.

About your connection issues: do you get any errors, calls to the beaconConnectionDidFail delegate?

Hi Piotr!

I don't have access to Xcode atm but - given what you say - I assume that the region is nil/null in regardless of which SDK I'm using. Will double check asap.

Regarding connection issues:
No, no delegates are invoked when the beacon I try to connect to has secure UUID activated. The beacon is indeed registered in my Estimote cloud and I authorize using ESTBeaconManager setupAppID [...]

Is there anything else I need to do in order to connect to a beacon with secure UUID? Perhaps something has changed since the secure feature was implemented.

Hey Max,

Just tried connecting to my secure beacon and it worked just fine, see the code below. I used SDK 2.3. One important thing in the snippet below: note that I'm holding a strong reference to the ESTBeacon object for the duration of connection. My first iteration wasn't doing that and it didn't work either, so maybe that's the problem?

let beaconManager = ESTBeaconManager()
let region = ESTBeaconRegion(proximityUUID: NSUUID(UUIDString: "B9407F30-F5F8-466E-AFF9-25556B57FE6D"), major: 8049, minor: 58243, identifier: "ice", secured: true)

var beacon: ESTBeacon!

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    ESTConfig.setupAppID("xxx", andAppToken: "xxx")

    beaconManager.requestAlwaysAuthorization()
    beaconManager.delegate = self

    beaconManager.startRangingBeaconsInRegion(region)

    return true
}

func beaconManager(manager: ESTBeaconManager!, didRangeBeacons beacons: [ESTBeacon]!, inRegion region: ESTBeaconRegion!) {
    println("didRangeBeacons, count = \(beacons.count)")
    if let beacon = beacons.first {
        self.beacon = beacon
        beaconManager.stopRangingBeaconsInRegion(self.region)
        beacon.delegate = self
        beacon.connect()
    }
}

func beaconConnectionDidSucceeded(beacon: ESTBeacon!) {
    println("beaconConnectionDidSucceeded")
    beacon.disconnect()
}

func beaconConnectionDidFail(beacon: ESTBeacon!, withError error: NSError!) {
    println("beaconConnectionDidFail, error = \(error)")
}

Hi Piotr!

After updating to SDK 2.3 (which wasn't available via Cocoapods when I opened the thread) and keeping a strong reference to the ESTBeacon object, I succeeded connecting to a beacon with secure UUID. Thanks!

While we're at it:
Another issue I'm facing, which I haven't managed to solve, is that the beaconDidDisconnect method is never called.

When a beacon is connected to, this code runs:

-(void)beaconConnectionDidSucceeded:(ESTBeacon *)beacon {

NSLog(@"Connected to beacon %@", beacon); //message is logged
[beacon disconnect]; //I've also tried [self.selectedBeacon disconnect]; which is a strong reference to the beacon object the app is connected to
}

However, below method is never invoked:

-(void)beaconDidDisconnect:(ESTBeacon *)beacon withError:(NSError *)error {

NSLog(@"Disconnected from beacon %@ with error: %@", beacon, error); //Nothing happens; log message doesn't appear
}

Am I missing something or is it a bug in the SDK?

Note that this issue has got nothing to do with whether the beacon connected to is secure or not.

Thanks a lot for your help.

Hey Max,

Note that the method signature for the didDisconnect delegate is:

- (void)beacon:(ESTBeacon *)beacon didDisconnectWithError:(NSError *)error

...which is different from what you have in your code:

-(void)beaconDidDisconnect:(ESTBeacon *)beacon withError:(NSError *)error

I always say that typos is the worst nightmare of all programmers (:

Haha, oh my. Thanks for solving that silly head-scratcher.