Triggers and Events

This guide will walk you through the basic configuration of BCTriggers.

Beacon triggers apply a series of filters to make triggering an action in a desired location easy. Stack filters to sequentially filter a micro-location down to your desired scenario.

Example One For example, in a certain section of your app you may want to display something when the device is near particular beacons under certain conditions:

  • only in a particular site
  • in range of a beacon with a specific category
  • has been in range for at least 5 seconds
  • when the device is closer than 3 meters of the beacon

Example Two In another section of your app, you want to welcome people with your app to your desk using the following conditions:

  • only in a particular site
  • in range of a beacon with a specific category
  • has been in range for at least 5 seconds without being out of range for more than 2 seconds
  • when the device is closer than 2 meters of the beacon

Set-Up

Android

In Android, create a BCEventManagerCallback:

Java
private final BCEventManagerCallback mEventManagerCallback = new BCEventManagerCallback()
{
	@Override
	public void onTriggeredEvent( final BCTriggeredEvent bcTriggeredEvent )
	{
    	//we'll fill this in later
	}
};

iOS

Objective-C
#import "ViewController.h"
#import "BlueCatsSDK.h"

@interface ViewController () <BCEventManagerDelegate>

//define some trigger identifiers
#define TRIGGER_IDENTIFIER_CHANGED_EXHIBIT @"trigger_identifier_changed_exhibit"
#define TRIGGER_IDENTIFIER_AT_DESK @"trigger_identifier_at_desk"

@end

@implementation FirstViewController

- (void)viewDidLoad {
    [super viewDidLoad];

		//set yourself as the delegate of the shared manager
    [[BCEventManager sharedManager] setDelegate:self];
}
Swift
import BlueCatsSDK  //or BCEventManager and BCTrigger if using SDK<2.0.0

class ViewController: UIViewController, BCEventManagerDelegate

	//define some trigger identifiers
	let TRIGGER_IDENTIFIER_AT_DESK = "trigger_identifier_at_desk"
	let TRIGGER_IDENTIFIER_CHANGED_EXHIBIT = "trigger_identifier_changed_exhibit"

	override func viewDidLoad() {
			super.viewDidLoad()

  		BCEventManager.sharedManager().delegate = self
	}

Example One

Trigger an event whenever a device moves to a new exhibit in a gallery and monitor for the event using the BCEventManagerDelegate.

Java
private void monitorCurrentGalleryExhibitChanged()
{
	//Set up filters to apply to ranged beacons
	final List<IBCEventFilter> filters = Arrays.asList(

		//Only include beacons in the site named 'Art Gallery'
		BCEventFilter.filterBySitesNamed( Arrays.asList(
			"Art Gallery"
		) ),

		//Only beacons tagged with a category named 'Exhibit'
		BCEventFilter.filterByCategoriesNamed( Arrays.asList(
			"Exhibit"
		) ),

		//Only allow beacons that have been in range for at least 5 seconds (we don't care about maxTimeIntervalNotMatched)
		BCEventFilter.filterByMinTimeIntervalBeaconMatched( 5000, Long.MAX_VALUE ),

		//Only include beacons when they are detected as less than approximately 3 meters away
		BCEventFilter.filterByAccuracyRangeFrom( 0.0, 3.0 ),

		//Apply additional smoothing of changes in RSSI and accuracy
		BCEventFilter.filterApplySmoothedRSSIOverTimeInterval( 5000 ),

		//Only fire the event when the closest beacon passing the previous tests changes
		BCEventFilter.filterByClosestBeaconChanged()
	);

	//Create a trigger with a custom identifier and pass our filters to it
	final BCTrigger changedGalleryExhibitTrigger = new BCTrigger( "ChangedGalleryExhibitTrigger", filters );

	//Set the repeat count for the event to fire indefinitely
	changedGalleryExhibitTrigger.setRepeatCount( Integer.MAX_VALUE );

	//Send the trigger to the event manager to be monitored
	BCEventManager.getInstance().monitorEventWithTrigger( changedGalleryExhibitTrigger, mEventManagerCallback );
}
Objective-C
- (void)monitorCurrentGalleryExhibitChanged
{
    //Set up filters to apply to ranged beacons
    NSMutableArray* filters = [[NSMutableArray alloc] init];

    //Only include beacons in the site named 'Art Gallery'
    [filters addObject:[BCEventFilter filterBySitesNamed:@[@"Art Gallery"]]];

    //Only beacons tagged with a category named 'Exhibit'
    [filters addObject:[BCEventFilter filterByCategoriesNamed:@[@"Exhibit"]]];

    //Apply additional smoothing of changes in accuracy
    [filters addObject:[BCEventFilter filterApplySmoothedAccuracyOverTimeInterval:5.0]];

    //Only include beacons when they are detected as less than approximately 3 meters away
    [filters addObject:[BCEventFilter filterByAccuracyRangeFrom:0.0 to:3.0]];

    //Only fire the event when the closest beacon passing the previous tests changes
    [filters addObject:[BCEventFilter filterByClosestBeaconChanged]];

    //Create the trigger
    BCTrigger* changedGalleryExhibitTrigger = [[BCTrigger alloc] initWithIdentifier:TRIGGER_IDENTIFIER_CHANGED_EXHIBIT andFilters:filters];

    //Set the repeat count for the event to fire indefinitely
    changedGalleryExhibitTrigger.repeatCount = NSIntegerMax;

    //Send the trigger to the event manager to be monitored
		[[BCEventManager sharedManager] monitorEventWithTrigger:changedGalleryExhibitTrigger];
}
Swift
func monitorCurrentGalleryExhibitChanged() {
    //Set up filters to apply to ranged beacons
    var filters: Array<BCEventFilterProtocol> = []

    //Only include beacons in the site named 'Art Gallery'
    filters.append(BCEventFilter.filterBySitesNamed(["Art Gallery"]))

    //Only beacons tagged with a category named 'Exhibit'
    filters.append(BCEventFilter.filterByCategoriesNamed(["Exhibit"]))

    //Apply additional smoothing of changes in accuracy
    filters.append(BCEventFilter.filterApplySmoothedAccuracyOverTimeInterval(5.0))

    //Only include beacons when they are detected as less than approximately 3 meters away
    filters.append(BCEventFilter.filterByAccuracyRangeFrom(0.0, to: 3.0))

    //Only fire the event when the closest beacon passing the previous tests changes
    filters.append(BCEventFilter.filterByClosestBeaconChanged())

    //Create the trigger
    let changedGalleryExhibitTrigger = BCTrigger.init(identifier: "trigger_identifier_changed_exhibit", andFilters: filters)

    changedGalleryExhibitTrigger.repeatCount = NSIntegerMax

    //Send the trigger to the event manager to be monitored
		BCEventManager.sharedManager().monitorEventWithTrigger(changedGalleryExhibitTrigger)
}

Note the repeatCount setting to have the event triggered more than once. You can also add the trigger to the event manager with the restoreTriggeredCount set to NO in iOS.

Example Two

Trigger an event when a device is near your desk for more than 5 seconds with a callback/completion block to fire when the trigger is satisfied.

Java
private void monitorAtMyDesk()
{
	//Set up filters to apply to ranged beacons
	final List<IBCEventFilter> filters = Arrays.asList(

		//Only include beacons in the site named "Office"
		BCEventFilter.filterBySitesNamed( Arrays.asList(
			"Office"
		) ),

		//Only beacons tagged with a category named "Desk"
		BCEventFilter.filterByCategoriesNamed( Arrays.asList(
			"Desk"
		) ),

		//Needs to pass the previous conditions for at least 5 seconds before firing, allowing a gap of at most 2 seconds within that time.
		BCEventFilter.filterByMinTimeIntervalBeaconMatched( 5000, 2000 ),

		//Within approximately 2 meters of the beacon
		BCEventFilter.filterByAccuracyRangeFrom( 0.0, 2.0 )
	);

	//Create the trigger
	final BCTrigger atMyDeskTrigger = new BCTrigger( "AtMyDeskTrigger", filters );

	//Send the trigger to the event manager to be monitored
	BCEventManager.getInstance().monitorEventWithTrigger( atMyDeskTrigger, mEventManagerCallback );
}
Objective-C
- (void)monitorAtMyDesk
{
    //Set up filters to apply to ranged beacons
    NSMutableArray* filters = [[NSMutableArray alloc] init];

    //Only include beacons in the site named 'Office'
    [filters addObject:[BCEventFilter filterBySitesNamed:@[@"Office"]]];

    //Only beacons tagged with a category named 'Desk'
    [filters addObject:[BCEventFilter filterByCategoriesNamed:@[@"Desk"]]];

    //Within approximately 2 meters of the beacon
    [filters addObject:[BCEventFilter filterByAccuracyRangeFrom:0.0 to:2.0]];

    //Needs to pass the previous conditions for at least 5 seconds before firing, allowing a gap of at most 2 seconds within that time.
    [filters addObject:[BCEventFilter filterByMinTimeIntervalBeaconMatched:5.0 allowingMaxTimeIntervalNotMatched:2.0]];

    //Create the trigger
    BCTrigger* atMyDeskTrigger = [[BCTrigger alloc] initWithIdentifier:TRIGGER_IDENTIFIER_AT_DESK andFilters:filters];

    //Send the trigger to the event manager to be monitored
		[[BCEventManager sharedManager] monitorEventWithTrigger:atMyDeskTrigger];
}
Swift
func monitorAtMyDesk() {
    //Set up filters to apply to ranged beacons
    var filters: Array<BCEventFilterProtocol> = []

    //Only include beacons in the site named 'Office'
    filters.append(BCEventFilter.filterBySitesNamed(["Office"]))

    //Only beacons tagged with a category named 'Desk'
    filters.append(BCEventFilter.filterByCategoriesNamed(["Desk"]))

    //Within approximately 2 meters of the beacon
    filters.append(BCEventFilter.filterByAccuracyRangeFrom(0.0, to: 2.0))

    //Needs to pass the previous conditions for at least 5 seconds before firing, allowing a gap of at most 2 seconds within that time.
    filters.append(BCEventFilter.filterByMinTimeIntervalBeaconMatched(5.0, allowingMaxTimeIntervalNotMatched: 2.0))

    //Create the trigger
    let atMyDeskTrigger = BCTrigger.init(identifier: TRIGGER_IDENTIFIER_AT_DESK, andFilters: filters)

    //Send the trigger to the event manager to be monitored
		BCEventManager.sharedManager().monitorEventWithTrigger(atMyDeskTrigger)
}

Adding the Trigger

Don’t forget to add your trigger to the event manager by calling your function(s)!

Java
monitorCurrentGalleryExhibitChanged();
monitorAtMyDesk();
Objective-C
[self monitorCurrentGalleryExhibitChanged];
[self monitorAtMyDesk];
Swift
monitorCurrentGalleryExhibitChanged()
monitorAtMyDesk()

Handle the Triggered Event

Java
private final BCEventManagerCallback mEventManagerCallback = new BCEventManagerCallback()
{
	@Override
	public void onTriggeredEvent( final BCTriggeredEvent triggeredEvent )
	{
		//If this BCEventManagerCallback is only assigned to one trigger, we don't need to check the identifier name
		//If there are multiple triggers calling the same callback, then we should check their identifier names to determine which one is calling the callback
		if( triggeredEvent.getEvent().getEventIdentifier().equals( "ChangedGalleryExhibitTrigger" ) )
		{
			//Display content for the new exhibit
			//Triggered event contains summary information about the trigger
			final int numberOfExhibitsVisited = triggeredEvent.getTriggeredCount();
			final Date firstExhibitVisitedAt = triggeredEvent.getFirstTriggeredAt();

			//Triggered event also contains a BCMicroLocation object containing the remaining
			//filtered beacons and their sites which triggered the event
			final BCBeacon newExhibitBeacon = triggeredEvent.getFilteredMicroLocation().getBeacons().get( 0 );
			final BCSite gallerySite = triggeredEvent.getFilteredMicroLocation().getSites().get( 0 );
		}
		else if( triggeredEvent.getEvent().getEventIdentifier().equals( "AtMyDeskTrigger" ) )
		{
            //Welcome to my desk!
        }
    }
};
Objective-C
-(void)eventManager:(BCEventManager *)eventManager triggeredEvent:(BCTriggeredEvent *)triggeredEvent
{
    if ([triggeredEvent.event.eventIdentifier isEqualToString:TRIGGER_IDENTIFIER_CHANGED_EXHIBIT]) {
        //Display content for the new exhibit
        //Triggered event contains summary information about the trigger
        NSInteger numberOfExhibitsVisited = triggeredEvent.triggeredCount;
        NSDate* firstExhibitVisitedAt = triggeredEvent.firstTriggeredAt;

        //Triggered event also contains a BCMicroLocation object containing the remaining
        //filtered beacons and their sites which triggered the event
        BCBeacon* newExhibitBeacon = [triggeredEvent.filteredMicroLocation.beacons firstObject];
        BCSite* gallerySite = [triggeredEvent.filteredMicroLocation.sites firstObject];

    } else if ([triggeredEvent.event.eventIdentifier isEqualToString:TRIGGER_IDENTIFIER_AT_DESK]) {
        //Welcome to my desk!
    }
}
Swift
func eventManager(eventManager: BCEventManager!, triggeredEvent: BCTriggeredEvent!) {
    if (triggeredEvent.event.eventIdentifier == TRIGGER_IDENTIFIER_CHANGED_EXHIBIT){
        //Display content for the new exhibit
        //Triggered event contains summary information about the trigger
        var numberOfExhibitsVisited = triggeredEvent.triggeredCount
        var firstExhibitVisitedAt = triggeredEvent.firstTriggeredAt

        //Triggered event also contains a BCMicroLocation object containing the remaining
        //filtered beacons and their sites which triggered the event
        var newExhibitBeacon = triggeredEvent.filteredMicroLocation.beacons().first
        var gallerySite = triggeredEvent.filteredMicroLocation.sites.first
    } else if (triggeredEvent.event.eventIdentifier == TRIGGER_IDENTIFIER_AT_DESK){
      //Welcome to my desk!
    }
}

Do a happy dance when your trigger is fired. 💃