Search code examples
angularjscordovaionic-frameworkibeaconestimote

Ionic application not detecting iBeacons on iOS (cordova-plugin-estimote)



I am currently working on a hybrid application (Ionic) and have a problem with detecting iBeacons on iOS (currently developing on 9.2). I'm using cordova-plugin-estimote (https://github.com/evothings/phonegap-estimotebeacons) to detect beacons, followed their documentation and everything works fine on Android, but not on iOS. The beacons are simply not detected. There is no error, it just doesn't find anything.

Fun fact: When I downloaded the original estimote app on iPhone, it also did not detect any iBeacons until I logged in. After that, it started detecting them normally. Why is this happening?

Relevant part of my AngularJS code based on plugin documentation:

$scope.init = function() {
  bluetoothSerial.isEnabled(scanBeacons, errorBluetooth);
}

function scanBeacons() {
  startScanning();
  updateList = $interval(updateView, 5000);
}

function startScanning() {
  console.log("requesting permissions");
  estimote.beacons.requestAlwaysAuthorization(successAuth, errorAuth);
}

function successAuth(){
  console.log("success auth, starting scan");
    estimote.beacons.startRangingBeaconsInRegion(
      {},
      onMonitoringSuccess,
      onError);
}

function errorAuth(){
  console.log("error auth");
  popupService.showPopup("Authorization error", "Location services required to perform scanning");
}

function onMonitoringSuccess(regionState) {
  console.log("monitoring success: "+JSON.stringify(regionState));
  var successHandler = function (response) {
    $scope.downloadedlist = response;
    $scope.offline = false;
  };
  var errorHandler = function (response) {
    $scope.beaconList = regionState.beacons;
  };
  eventService.getBeaconList(regionState.beacons, storageService.getEventId())
    .then(successHandler)
    .catch(errorHandler);
}

function onError(response) {
  console.log("monitoring error: "+JSON.stringify(response));
  popupService.showPopup('popup.error.title', 'popup.error.server');
}

As you can see, I have some console.log statements (it has to be done this way) and I'm getting "requesting permissions", instantly followed by "success auth, starting scan". It's weird because authorization popup is displayed but the code does not wait for the user input, it just automatically fires success handler (successAuth) function and that's it. No more logs, which means no monitoring success, no error, it just doesn't find any beacons.

Any help appreciated. Thanks.


Solution

  • Finally found the solution. The problem was here:

    estimote.beacons.startRangingBeaconsInRegion(
      {},
      onMonitoringSuccess,
      onError);
    

    Turns out Android allows for {} parameter (which means look for all regions) in the following function but iOS doesn't. After specifying a region, my application successfuly finds the beacons.

    Example:

    function successAuth(){
     console.log("success auth, starting scan");
     var region = { uuid: 'YOUR_UUID_HERE' }
     estimote.beacons.startRangingBeaconsInRegion(
      region,
      onMonitoringSuccess,
      onError);
    }
    

    Estimote Developer quote:

    iOS only allows scanning for beacons the UUID of which you know. All Estimote Beacons ship with our default UUID, "B9407F30-F5F8-466E-AFF9-25556B57FE6D", and these are the beacons you can see on the radar even when not logged in. If you change this UUID to something else, then you need to stay logged in so that Estimote app can know what the UUIDs of your beacons are, and scan for them in addition to the default UUID.

    Source: https://forums.estimote.com/t/beacons-not-detected-using-estimote-ios-app/1580/5

    This also explains why Estimote App started detecting iBeacons after logging in.