iBeacon iOS Documentation

Last updated: Jan 06th, 2017

Getting Started

Beacon module is one of Mesosfer module that has specific feature to manage beacon activities.

Storyline

This module used for showing a “story” when beacons are detected or in range e.g. museum, merchant shop, etc. Y0u can manage what “story” that need to show to the end users when detected beacon e.g. some alert text or notification, displaying an image campaign, playing a video campaign or maybe open some website. You can also choose when the “story” must displayed based on beacon’s event :

  • Enter, triggered when user entering region of a beacon
  • Exit, triggered when user exiting region of a beacon
  • Immediate, triggered when user range approximately <1 meter from beacon
  • Near, triggered when user range approximately within 1-3 meters from beacon
  • Far, triggered when user range approximately >3 meters from beacon

Besides, you can select what days to show when “story” was triggered. By using a storyline, you can manage multiple beacon’s “story”.

Presence

This module can be used to tracking any check-in and check-out data e.g. employee attendance, student presence, etc.

Notification

This module is the simple version of storyline, it can only manage a beacon for each notification e.g. show a greeting when user entering shop.

Microlocation

This module can be used for track indoor location using a mapped beacon in an area.

Module Beacon

Mesosfer provide a specialized bucket Beacon that automatically handles much of the functionality required for beacon management.

Objects and Types

Here is some predefined Beacon object :

  • name => NSString, define the name of a beacon.
  • uuid => NSUUID, define the proximity UUID of a beacon. Most commonly represented as a string, e.g. CB10023F-A318-3394-4199-A8730C7C1AEC.
  • major => NSNumber, define the major number of a beacon. An unsigned short integer, i.e., an integer ranging from 1 to 65535, (0 is a reserved value).
  • minor => NSNumber, define the minor number of a beacon. Also an unsigned short integer, like the major number.
  • metadata => NSDictionary, define custom object of a beacon.

Saving Beacons

Let’s say you want to save the MFBeacon described above to the Mesosfer Cloud. The interface is similar to a NSDictionary, plus the saveAsyncWithBlock: method:

// create object beacon with name
MFBeacon *beacon = [MFBeacon beaconWithName:@"Cubeacon"];
// set proximity UUID of beacon
beacon.proximityUUID = [[NSUUID alloc] initWithUUIDString:@"CB10023F-A318-3394-4199-A8730C7C1AEC"];
// set major number of beacon
beacon.major = @1;
// set minor number of beacon
beacon.minor = @284;
// set custom objects of beacon
beacon[@"identifier"] = @"Beacon-Red-Front-Gate-1-284";
beacon[@"timestamp"] = [NSDate date];
beacon[@"object"] = [NSDictionary dictionary];
beacon[@"array"] = [NSArray array];
// execute save async using block
[beacon saveAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
    if (!succeeded) {
        NSLog(@"Failed to save beacon, cause: %@", error);
        return;
    }

    NSLog(@"Beacon saved.");
}];

Retrieve Beacons

If you need to fetch a Beacon with the latest data that is in the cloud, you can call the fetchAsyncWithBlock: method like so:

// create beacon from existing objectId
MFBeacon *beacon = [MFBeacon beaconWithObjectId:@"beaconObjectId"];
// fetching the beacon data
[beacon fetchAsyncWithBlock:^(id  _Nullable object, NSError * _Nullable error) {
    if (error) {
        NSLog(@"Failed to fetch beacon, cause: %@", error);
        return;
    }

    NSLog(@"Beacon fetched.");
}];

This will automatically update beacon with the latest data from cloud.

Querying Beacon

There are many other ways to retrieve data with MFQuery. You can retrieve many data at once, put conditions on the data you wish to retrieve.

Basic Query

In many cases, there is a condition that need to specify which datas you want to retrieve. The MFQuery offers different ways to retrieve an array of MFBeacons. The general pattern is to create a MFQuery, put conditions on it, and then retrieve a NSArray of matching MFBeacons using the findAsyncWithBlock: method. For example, to retrieve MFBeacons data with a name, use the whereKey:equalTo: method to constrain the value for a key:

MFQuery *query = [MFBeacon query];
[query whereKey:BEACON_KEY_NAME equalTo:@"Beacon-Red-Front-Gate-1-284"];
[query findAsyncWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
    if (error) {
        NSLog(@"Failed to query beacon, cause: %@", error);
        return;
    }

    NSLog(@"Found beacon: %lu", objects.count);
}];

Query Constraint

Refer to this link to learn more about query constraint.

Update Beacon

After getting the MFBeacon data, you can update your data that stored in cloud using method saveAsyncWithBlock:.

MFBeacon *beacon; // fetched beacon data
// update beacon data
beacon.proximityUUID = [[NSUUID alloc] initWithUUIDString:@"11111111-2222-3333-4444-555555555555"];
beacon.major = @6;
beacon.minor = @7;
beacon[@"identifier"] = @"Beacon-Red-Waiting-Room-6-7";
beacon[@"timestamp"] = [NSDate date];
// execute save data
[beacon saveAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
    if (!succeeded) {
        NSLog(@"Failed to save beacon, cause: %@", error);
        return;
    }

    NSLog(@"Beacon saved.");
}];

Delete Beacon

To delete a MFBeacon from the Mesosfer Cloud, use method deleteAsyncWithBlock: :

// the current beacon object to delete
MFBeacon *beacon;
// execute delete beacon async
[beacon deleteAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
    if (!succeeded) {
        NSLog(@"Failed to delete beacon, cause: %@", error);
        return;
    }

    NSLog(@"Beacon deleted.");
}]

Module Presence

Mesosfer provide a specialized bucket Notification that automatically handles much of the functionality required for notification management.

Objects and Types

Here is some predefined Notification object :

  • beacon => MesosferBeacon, define the beacon object of a notification.
  • description => String, define the description of notification.
  • event => String, define the event name of a notification.
  • type => String, define the event type of a notification.
  • isEnabled => Boolean, define the state of notification whether it is enabled or not.
  • message => Object, define custom object of a notification.

Saving Notifications

Let’s say you want to save the MFNotification described above to the Mesosfer Cloud. The interface is similar to a NSDictionary, plus the saveAsyncWithBlock: method:

// create new notification object using beacon objectId
MFNotification *notif = [MFNotification notificationWithBeaconId:@"beaconObjectId"];
// set description
notif.notifDescription = @"Monday-Notification";
// set state whether it is enabled or not
notif.isEnabled = true;
// set beacon event
notif.event = MFBeaconEventEnter;
// set notification type
notif.type = MFNotificationTypeText;
// set custom objects
notif[@"alertTitle"] = @"Hello, good morning.";
notif[@"alertMessage"] = @"How is your weekend? It's great, isn't it? Have a nice day.";
notif[@"timestamp"] = [NSDate date];
notif[@"object"] = [NSDictionary dictionary];
notif[@"array"] = [NSArray array];
// execute save async using block
[notif saveAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
    if (!succeeded) {
        NSLog(@"Failed to save notification, cause: %@", error);
        return;
    }

    NSLog(@"Notification saved.");
}];

Retrieve Notifications

If you need to fetch a Notification with the latest data that is in the cloud, you can call the fetchAsyncWithBlock: method like so:

// create notification from existing objecId
MFNotification *notif = [MFNotification notificationWithObjectId:@"notificationObjectId"];
// fetching the notification data
[notif fetchAsyncWithBlock:^(id  _Nullable object, NSError * _Nullable error) {
    if (error) {
        NSLog(@"Failed to fetch notification, cause: %@", error);
        return;
    }

    NSLog(@"Notification fetched.");
}];

This will automatically update notif with the latest data from cloud.

Querying Notification

There are many other ways to retrieve data with MFQuery. You can retrieve many data at once, put conditions on the data you wish to retrieve.

Basic Query

In many cases, there is a condition that need to specify which datas you want to retrieve. The MFQuery offers different ways to retrieve an array of MFNotifications. The general pattern is to create a MFQuery, put conditions on it, and then retrieve a NSArray of matching MFNotifications using the findAsyncWithBlock: method. For example, to retrieve MFNotifications data with a type, use the whereKey:equalTo: method to constrain the value for a key:

MFQuery *query = [MFNotification query];
[query whereKey:NOTIFICATION_KEY_TYPE equalTo:@(MFNotificationTypeText)];
[query findAsyncWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
    if (error) {
        NSLog(@"Failed to query notification, cause: %@", error);
        return;
    }

    NSLog(@"Found notification: %lu", objects.count);
}];

Query Constraint

Refer to this link to learn more about query constraint.

Update Notification

After getting the MFNotification data, you can update your data that stored in cloud using method saveAsyncWithBlock:.

MFNotification *notif; // fetched notification data
// update notification data
notif.event = MFBeaconEventExit;
notif.type = MFNotificationTypeImage;
notif[@"timestamp"] = [NSDate date];
notif[@"urlImageIOS"] = @"http://image.com/image-ios-640x1136.png";
// execute save notification data
[notif saveAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
    if (!succeeded) {
        NSLog(@"Failed to update notification, cause: %@", error);
        return;
    }

    NSLog(@"Notification updated.");
}];

Delete Notification

To delete a MFNotification from the Mesosfer Cloud, use method deleteAsyncWithBlock: :

// the current notification object to delete
MFNotification *notif;
// execute delete notification async
[notif deleteAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
    if (!succeeded) {
        NSLog(@"Failed to delete notification, cause: %@", error);
        return;
    }

    NSLog(@"Notification deleted.");
}];

Module Storyline

Mesosfer provide a specialized bucket Storyline that automatically handles much of the functionality required for storyline management.

Objects and Types

Here is some predefined Storyline object :

  • title => NSString, define the title of a storyline.
  • isEnabled => Boolean, define the state of storyline, whether it is enabled or not.

Saving Storylines

Let’s say you want to save the MFStoryline described above to the Mesosfer Cloud with saveAsyncWithBlock: method:

// create new storyline object with title
MFStoryline *storyline = [MFStoryline storylineWithTitle:@"Entering-region-storyline"];
// set isEnabled
storyline.isEnabled = YES;
// execute save async using callback
[storyline saveAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
    // check if there is an exception happen
    if (error) {
        NSLog(@"Error saving storyline, cause: %@", error);
        return;
    }

    NSLog(@"Storyline saved.");
}];

Retrieve Storylines

If you need to fetch a Storyline with the latest data that is in the cloud, you can call the fetchAsyncWithBlock: method like so:

// create storyline from existing objecId
MFStoryline *storyline = [MFStoryline storylineWithObjectId:@"storylineObjectId"];
[storyline fetchAsyncWithBlock:^(id  _Nullable object, NSError * _Nullable error) {
    // check if there is an exception happen
    if (error) {
        NSLog(@"Error fetching storyline, cause: %@", error);
        return;
    }

    NSLog(@"Storyline fetched.");
}];

This will automatically update storyline with the latest data from cloud.

Querying Storyline

There are many other ways to retrieve data with MFQuery. You can retrieve many data at once, put conditions on the data you wish to retrieve.

Basic Query

In many cases, there is a condition that need to specify which datas you want to retrieve. The MFQuery offers different ways to retrieve an array of MFStorylines. The general pattern is to create a MFQuery, put conditions on it, and then retrieve a NSArray of matching MFStorylines using the findAsyncWithBlock: method. For example, to retrieve MFStorylines data where isEnabled, use the whereEqualTo method to constrain the value for a key:

MFQuery *query = [MFStoryline query];
[query whereKey:STORYLINE_KEY_IS_ENABLED equalTo:@YES];
[query findAsyncWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
    if (error) {
        NSLog(@"Error finding storyline, cause: %@", error);
        return;
    }

    NSLog(@"Found storyline: %lu", objects.count);
}];

Query Constraint

Refer to this link to learn more about query constraint.

Update Storyline

After getting the MFStoryline data, you can update your data that stored in cloud using method saveAsyncWithBlock:.

MFStoryline *storyline; // fetched storyline data
// update Storyline data
storyline.title = @"Exiting-region-storyline";
storyline.isEnabled = NO;
// execute save data
[storyline saveAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
    // check if there is an exception happen
    if (error) {
        NSLog(@"Error updating storyline, cause: %@", error);
        return;
    }

    NSLog(@"Storyline updated.");
}];

Delete Storyline

To delete a MFStoryline from the Mesosfer Cloud, use method deleteAsyncWithBlock: :

// the current Storyline object to delete
MFStoryline *storyline;
// execute delete storyline async
[storyline deleteAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
    // check if there is an exception happen
    if (error) {
        NSLog(@"Error deleting storyline, cause: %@", error);
        return;
    }

    NSLog(@"Storyline deleted.");
}];

Module Storyline Detail

Mesosfer provide a specialized bucket StorylineDetail that automatically handles much of the functionality required for storyline management.

Objects and Types

Here is some predefined StorylineDetail object :

  • event => NSString, define the event name of a storyline.
  • campaign => NSString, define the campaign type of a storyline.
  • beacons => NSArray, define array of beacon of a storyline.
  • showOn => NSArray, define array of key and value pairs within day name and boolean state of a storyline.
  • alertTitle => NSString, define the alert title of storyline, used for TEXT campaign.
  • alertMessage => NSString, define the alert message of storyline, used for TEXT campaign.
  • urlImageAndroid => NSString, define the url image for Android of storyline, used for IMAGE campaign.
  • urlImageiOS => NSString, define the url image for iOS of storyline, used for IMAGE campaign.
  • urlPage => NSString, define the url page of storyline, used for URL campaign.
  • urlVideo => NSString, define the url video of storyline, used for VIDEO campaign.

Saving Storyline Details

Let’s say you want to save the MFStorylineDetail described above to the Mesosfer Cloud with saveAsyncWithBlock: method:

// Storyline object
MFStoryline *storyline;

// create new Storyline Detail object
MFStorylineDetail *detail = [MFStorylineDetail storylineDetailWithStoryline:storyline];
// set campaign
detail.campaign = MFStorylineCampaignVideo;
// set event
detail.event = MFBeaconEventImmediate;
// set alert title
detail.alertTitle = @"App Notification";
// set alert message
detail.alertMessage = @"You have a notification.";
// set url video
detail.urlVideo = @"https://youtube.com/watch?v=mesosfer-video-campaign";

// set beacon list
NSArray<MFBeacon *> *beaconList;
detail.beacons = beaconList;
// set show on
MFShowDay *showOn = [[MFShowDay alloc] init];
[showOn enableAllDay];
detail.showOn = showOn;

// execute saving storyline detail
[detail saveAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
    // check if there is an exception happen
    if (error) {
        NSLog(@"Error saving storyline detail, cause: %@", error);
        return;
    }

    NSLog(@"Storyline detail successfully saved.");
}];

Retrieve Storyline Details

If you need to fetch a StorylineDetail with the latest data that is in the cloud, you can call the fetchAsyncWithBlock: method like so:

// create storyline detail from existing objecId
MFStorylineDetail *detail = [MFStorylineDetail storylineDetailWithObjectId:@"storylineDetailObjectId"];
// fetching the storyline detail data
[detail fetchAsyncWithBlock:^(id  _Nullable object, NSError * _Nullable error) {
    // check if there is an exception happen
    if (error) {
        NSLog(@"Error while fetching storyline detail, cause %@", error);
        return;
    }

    NSLog(@"Storyline detail fetched.");
}];

This will automatically update detail with the latest data from cloud.

Querying Storyline

There are many other ways to retrieve data with MFQuery. You can retrieve many data at once, put conditions on the data you wish to retrieve.

Basic Query

In many cases, there is a condition that need to specify which datas you want to retrieve. The MFQuery offers different ways to retrieve an array of MFStorylines. The general pattern is to create a MFQuery, put conditions on it, and then retrieve a NSArray of matching MFStorylineDetails using the findAsyncWithBlock: method. For example, to retrieve MFStorylines data with campaign VIDEO and event ENTER, use the whereEqualTo method to constrain the value for a key:

MFQuery *query = [MFStorylineDetail query];
[query whereKey:STORYLINE_DETAIL_KEY_CAMPAIGN equalTo:@(MFStorylineCampaignVideo)];
[query whereKey:STORYLINE_DETAIL_KEY_EVENT equalTo:@(MFBeaconEventEnter)];
[query findAsyncWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
    if (error) {
        NSLog(@"Error while finding storyline detail, cause %@", error);
        return;
    }

    NSLog(@"Found storyline detail: %lu", objects.count);
}];

Query Constraint

Refer to this link to learn more about query constraint.

Update Storyline

After getting the MFStorylineDetail data, you can update your data that stored in cloud using method saveAsyncWithBlock.

MFStorylineDetail *detail; // fetched storyline detail data
// update storyline detail data
detail.urlVideo = @"https://youtube.com/watch?v=cubeacon-video-campaign";
detail.event = MFBeaconEventNear;
// execute save data
[detail saveAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
    if (error) {
        NSLog(@"Error while updating storyline detail, cause %@", error);
        return;
    }

    NSLog(@"Storyline detail updated.");
}];

Delete Storyline Detail

To delete a MFStorylineDetail from the Mesosfer Cloud, use method deleteAsyncWithBlock: :

// the current Storyline object to delete
MFStorylineDetail *detail;
// execute delete storyline async
[detail deleteAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
    // check if there is an exception happen
    if (error) {
        NSLog(@"Error deleting storyline detail, cause: %@", error);
        return;
    }

    NSLog(@"Storyline detail deleted.");
}];

Module Log

Within Beacon modules, Mesosfer provide a specialized bucket Log that use for logging.

Objects and Types

Here is some predefined Log object :

  • beacon => NSString, define the beacon that detected.
  • event => NSString, define the event beacon that happen.
  • interval => NSNumber, define the interval between entering and exiting region of beacon.
  • module => NSString, define the module that used for logging. There are 4 modules :
    • MFBeaconModuleStoryline
    • MFBeaconModulePresence
    • MFBeaconModuleTagging
    • MFBeaconModuleMicrolocation

Sending Logs

Let’s say you want to send a MFLog to Mesosfer Cloud with sendAsyncWithBlock: method:

// create log object with beacon object, event and module
MFLog *log = [MFLog logWithBeacon:[MFBeacon beaconWithObjectId:@"beaconObjectId"]
                            event:MFBeaconEventFar
                           module:MFBeaconModuleStoryline];
[log sendAsyncWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
    // check if there is an exception happen
    if (error) {
        NSLog(@"Error sending log, cause: %@", error);
        return;
    }

    NSLog(@"Log sent.");
}];