Skip to content

Instantly share code, notes, and snippets.

@daniellevass
Last active March 15, 2019 08:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save daniellevass/d293943188af5724ae5e to your computer and use it in GitHub Desktop.
Save daniellevass/d293943188af5724ae5e to your computer and use it in GitHub Desktop.

iBeacon Cordova Plugin Cordova / Phonegap iBeacon plugin

Features

Features available on both Android and iOS

  • Ranging
  • Monitoring

Features exclusive to iOS

  • Region Monitoring (or geo fencing), works in all app states.
  • Advertising device as an iBeacon

Installation

cordova plugin add https://github.com/petermetz/cordova-plugin-ibeacon.git

Usage

The plugin's API closely mimics the one exposed through the CLLocationManager introduced in iOS 7 e.g. Ranging and Monitoring beacons.

Since version 2, the main IBeacon facade of the DOM is called LocationManager and it's API is based on promises instead of callbacks. Another important change of version 2 is that it no longer pollutes the global namespace, instead all the model classes and utilities are accessible through the cordova.plugins.locationManager reference chain.

Since version 3.2 the Klass dependency has been removed and therefore means creation of the delegate has changed.

iOS 8 Permissions

On iOS 8, you have to request permissions from the user of your app explicitly. You can do this through the plugin's API. See the LocationManager's related methods: requestWhenInUseAuthorization and requestWhenInUseAuthorization for further details.


Standard CLLocationManager functions

Typical iBeacon pattern
  1. Set up a region with a UUID of which all your iBeacons using.
  2. Monitor region - this listens for when the user "enters" or "exits" a region.
  3. When the user enters a region - begin ranging for specific beacons
  4. Google recommend stop scanning as early as possible to conserve users batteries.

Notes - monitoring appears broken on Android - solution is to instead range for beacons and determine yourself if you are in or out of a region


Setting Up

1 Creating a region

var region = new cordova.plugins.locationManager.BeaconRegion("region_identifier", "region_uuid");

You can also listen to specific beans by passing in a major and minor value like so:

var region = new cordova.plugins.locationManager.BeaconRegion("region_purple_estimote_beacon",
                "B9407F30-F5F8-466E-AFF9-25556B57FE6D", 16678, 58964);

2 Set up delegate

// create a delegate
var delegate = new cordova.plugins.locationManager.Delegate();

// called when user enters or exits a region
delegate.didDetermineStateForRegion = function (pluginResult) {
  log("did determine state for region "+ JSON.stringify(pluginResult));
};

// called every second, there is a list of beacons inside data.beacons
// will get called even if there are 0 beacons in the list
delegate.didRangeBeaconsInRegion = function (data) {
  log('didRangeBeaconsInRegion: ' + JSON.stringify(data) );
};

// called if anything fails
delegate.monitoringDidFailForRegionWithError = function(error) {
  log(JSON.stringify(error));  
};

//set the delegate
cordova.plugins.locationManager.setDelegate(delegate);

3 iOS only - request location permission - doesn't affect Android app

//asks user to allow the use of location monitoring.
cordova.plugins.locationManager.requestWhenInUseAuthorization();

4 start monitoring

cordova.plugins.locationManager.startMonitoringForRegion(beaconRegion);

5 Start Ranging

cordova.plugins.locationManager.startRangingBeaconsInRegion(beaconRegion);

6 Stop Ranging.

cordova.plugins.locationManager.stopRangingBeaconsInRegion(beaconRegion);

7 Stop Monitoring

cordova.plugins.locationManager.stopMonitoringForRegion(beaconRegion);

8 Notes

You can set up multiple regions (Apple will let you monitor up to 20) which will all use the same delegate - it will just call the didRangeBeaconsInRegion callback for each region, as the function brings back the region and a list of beacons you can easily determine which beacons are connected to which region. However, be sure to call startRanging and stopRanging on all the regions you care about :-)

Delegate CallBacks

delegate.didDetermineStateForRegion = function (pluginResult) {} pluginresult contains:

{
  "state": "CLRegionStateInside",
  "region": {
    "typeName": "BeaconRegion",
    "identifier": "beaconOnTheMacBooksShelf",
    "uuid": "b9407f30-f5f8-466e-aff9-25556b57fe6d"
  },
  "eventType": "didDetermineStateForRegion"
}

delegate.didRangeBeaconsInRegion = function (data) {} data contains:

{
  "region": {
    "typeName": "BeaconRegion",
    "uuid": "B9407F30-F5F8-466E-AFF9-25556B57FE6D",
    "identifier": "beaconOnTheMacBooksShelf"
  },
  "eventType": "didRangeBeaconsInRegion",
  "beacons": [
    {
      "minor": 34053,
      "rssi": -72,
      "major": 22258,
      "proximity": "ProximityNear",
      "accuracy": 0.77,
      "uuid": "B9407F30-F5F8-466E-AFF9-25556B57FE6D"
    },
    {
      "minor": 64448,
      "rssi": -95,
      "major": 48661,
      "proximity": "ProximityFar",
      "accuracy": 14.68,
      "uuid": "B9407F30-F5F8-466E-AFF9-25556B57FE6D"
    }
  ]
}

Determine if advertising is supported (iOS only)
cordova.plugins.locationManager.isAdvertisingAvailable()
    .then(function(isSupported){
        console.log("isSupported: " + isSupported);
    })
    .fail(console.error)
    .done();

Determine if advertising is currently turned on (iOS only)
cordova.plugins.locationManager.isAdvertising()
    .then(function(isAdvertising){
        console.log("isAdvertising: " + isAdvertising);
    })
    .fail(console.error)
    .done();

Start advertising device as an iBeacon (iOS only)
var uuid = 'DA5336AE-2042-453A-A57F-F80DD34DFCD9';
var identifier = 'advertisedBeacon';
var minor = 2000;
var major = 5;
var beaconRegion = new cordova.plugins.locationManager.BeaconRegion(identifier, uuid, major, minor);

// The Delegate is optional
var delegate = new cordova.plugins.locationManager.Delegate();

// Event when advertising starts (there may be a short delay after the request)
// The property 'region' provides details of the broadcasting Beacon
delegate.peripheralManagerDidStartAdvertising = function(pluginResult) {
    console.log('peripheralManagerDidStartAdvertising: '+ JSON.stringify(pluginResult.region));
};
// Event when bluetooth transmission state changes
// If 'state' is not set to BluetoothManagerStatePoweredOn when advertising cannot start
delegate.peripheralManagerDidUpdateState = function(pluginResult) {
    console.log('peripheralManagerDidUpdateState: '+ pluginResult.state);
};

cordova.plugins.locationManager.setDelegate(delegate);

// Verify the platform supports transmitting as a beacon
cordova.plugins.locationManager.isAdvertisingAvailable()
    .then(function(isSupported){

        if (isSupported) {
            cordova.plugins.locationManager.startAdvertising(beaconRegion)
                .fail(conole.error)
                .done();
        } else {
            console.log("Advertising not supported");
        }
    })
    .fail(console.error)
    .done();

Stopping the advertising (iOS only)
cordova.plugins.locationManager.stopAdvertising()
    .fail(console.error)
    .done();


Contributions

Contributions are welcome at all times, please make sure that the tests are running without errors before submitting a pull request. The current development branch that you should submit your pull requests against is "v3.x".


How to execute the tests - OS X

Prerequisites Of The Test Runner

dart test/run_tests.dart

Executing the test runner will do the following:

  • Generates a Cordova project
  • Add the iOS platform
  • Installs the iBeacon plugin from the local file-system.
  • Launches XCode by opening the project.

How to execute the tests - Without the Dart SDK

  • Open an app which has Cordova iBeacon plugin installed in XCode
  • Install it onto a device or simulator
  • Open Safari
  • Go to the dev tools window
  • Paste the code from the examples into the javascript console, it should run without any errors.
@mobigaurav
Copy link

can you put a example where we can see this plugin is working for multiple beacons?

@ChrisZio
Copy link

Hi, in your notes you refer to "region" and later on you refer to "beaconRegion", my assumption is that this is the same thing...right?

@usamaahsan21
Copy link

usamaahsan21 commented Mar 15, 2019

can this plugin work on windows ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment