What you will learn:

By integrating our SDK, you can display Notifications on your app when a beacon is detected nearby.

To make things easier, our SDK contains a default Auto Notification: this is a built-in notification that is automatically generated when a beacon is detected nearby, as soon as the SDK has been initialized in your app.

You also have the ability to configure custom-built notifications, using our model of interfaces and built-in objects.

In both cases, you can manage the content of your beacon notifications directly on our AdTag platform.

This tutorial tells you more about these Auto and custom-built beacon notifications, and how you can work with them.

Pre-requisites - What you need to get started

  • Your SDK credentials, including an SDK Login, Password, and Company Key to initialize the SDK.
  • A BLE beacon, which has been configured on your account, in order to test interactions with your app.
  • An iOS Device, with Bluetooth 4.0 and iOs 9 and above.
  • The Xcode application, which you can download from the App store.
  • You must have completed the 5 minutes QuickStart Tutorial.

Initialize the SDK

Step 1: Clone the sdk-tutorial repository

  • Clone the sdk-tutorial repository
git clone https://github.com/Connecthings/sdk-tutorial.git
  • Open the iOs>beacon>2-Notification>Notification-Starter folder

Step 2: Configure the SDK

  • Configure your CocoaPod files and .plist
  • Configure your SDK with:
    • the appropriate Adtag Environment (DEMO / PREPROD / PROD / PROD_US)
    • your SDK credentials

Switch to Swift

[[[ATAdtagInitializer sharedInstance] configureUrlType:ATUrlTypeProd
                                              andLogin:@"__USER__"
                                           andPassword:@"__PSWD__"
                                            andCompany:@"__COMPANY__"]
                                           synchronize];
AdtagInitializer.shared.configPlatform(platform: __UrlType__)
                       .configUser(login: __USER__, password: __PSWD__, company: __COMPANY__)
                       .synchronize()

If you need more informations, have a look to the 5 minutes quickstart tutorial

Step 3: Enable your app to receive local beacon Notifications

We invite you to read the 5 minutes QuickStart Tutorial to check the steps to receive the local beacon Notifications.

Customize your Auto Notifications

As a reminder, Auto Notifications are notifications generated by default by the SDK. You can manage their content (text – title & description - , URI, and content image), and disable them if necessary, directly from the AdTag platform, in the Application Management section.

Learn more on notification management in AdTag in the AdTag tutorial

Create custom-built notifications

If you would like to implement notifications that are more customizable than our Auto notifications, you can replace them with your own, custom-built, beacon notifications, as described in the following section.

Notification Model Overview

First, let’s go through an overview of the notification model, with the corresponding interfaces and built-in objects.

The AdtagNotificationTask

The AdtagNotificationTask is a delegate that allows your application to complete an asynchronous task of your choice before displaying a notification. A default implementation of this delegate is available. It's the NotificationImageTask: it directly downloads the notification image from AdTag, and when ready displays the notification with the corresponding image.

The method launchNotificationTask takes two parameters:

  • adtagPlaceNotification: the common object used by the SDK to deal with notification which contains Adtag data
  • displayPlaceNotificationListener: the object used to notify the SDK when the notification is ready to be displayed

The DisplayPlaceNotificationListener

The DisplayPlaceNotificationListener is an interface that is mainly in charge of displaying the notification linked with a beacon. Before a notification is triggered, the NotificationManager checks that the corresponding beacon is still within range. If so, the notification is displayed; otherwise, nothing appears to the end user. To notify the NotificationManager of the need to display a notification, you must call the displayPlaceNotification method, which takes a PlaceNotificationImage object as argument.

The NotificationBuilder

The NotificationBuilder interface allows you to create and customize your notifications.

If you want to create and use your own builder, you need to implement these two methods:

  • generateNotificationForIOS10AndPlus: use this function to generate and return an UNMutableNotificationContent, the method takes one argument - a PlaceNotificationImage.
  • generateNotificationForIOS9AndMinus: use this function to generate and return a UILocalNotification, the method takes one argument - a PlaceNotificationImage.

PlaceNotificationImage

A PlaceNotificationImage has 3 additional methods compared to the PlaceNotification object:

  • getImage: returns the bitmap associated with the notification image on AdTag
  • hasImage: returns true if the image bitmap is available
  • isWelcomeNotification: returns true if the associated placeNotification is a welcome notification

What can you customize ?

Two of the previous interfaces can permit you to customize the notification process:

  • The AdtagNotificationTask, which allows to associate additional content to the notification in an asynchronous way (as bitmap). This option will not be discussed in this document, but you can find a basic implementation to help you start in the notification demo code folder.
  • The NotificationBuilder, which allows to have a full control on the notification content and parameters. The next step will develop an implementation of the NotificationBuilder interface.

Step 1: Create your own NotificationBuilder

  • Create a new class named MyBeaconNotificationBuilder
  • In the MyBeaconNotificationBuilder.h file, implement the NotificationBuilder

Switch to Swift

#import <Foundation/Foundation.h>
#import <UserNotifications/UserNotifications.h>
#import "AdtagLocationBeacon-Swift.h"
#import "ConnectPlaceActions-Swift.h"

@interface MyBeaconNotificationBuilder : NSObject <NotificationBuilder> {

}

@end
import Foundation
import UserNotifications
import ConnectPlaceActions
import AdtagLocationBeacon

class MyBeaconNotificationBuilder: NSObject, NotificationBuilder {

}
  • Declare the generateNotificationForIOS10AndPlus method and the generateNotificationForIOS9AndMinus method in the MyBeaconNotificationBuilder.m file

Switch to Swift

@implementation MyBeaconNotificationBuilder

- (UNMutableNotificationContent * _Nonnull)generateNotificationForIOS10AndPlusWithPlaceNotificationImage:(PlaceNotificationImage * _Nonnull) placeNotificationImage {

}

- (UILocalNotification * _Nonnull)generateNotificationForIOS9AndMinusWithPlaceNotificationImage:(PlaceNotificationImage * _Nonnull)placeNotificationImage {

}

@end
func generateNotificationForIOS10AndPlus(placeNotificationImage: PlaceNotificationImage) -> UNMutableNotificationContent {

}

func generateNotificationForIOS9AndMinus(placeNotificationImage: PlaceNotificationImage) -> UILocalNotification {

}

Step 2: Generate the local notification

  • Generate your notification based on the IOS version:

Switch to Swift

- (UNMutableNotificationContent * _Nonnull)generateNotificationForIOS10AndPlusWithPlaceNotificationImage:(PlaceNotificationImage * _Nonnull) placeNotificationImage {
    UNMutableNotificationContent *notificationContent = [[UNMutableNotificationContent alloc] init];

    AdtagPlaceNotification *placeNotification = [placeNotificationImage getPlaceNotification];

    if([placeNotification getDescription].length <= 0) {
        notificationContent.body = [placeNotification getTitle];
    }else{
        notificationContent.body = [placeNotification getDescription];
    }
    if([placeNotification getTitle].length > 0) {
        notificationContent.title = [placeNotification getTitle];
    }

    if (placeNotificationImage.hasImage) {
        UNNotificationAttachment *attachement1 = [UNNotificationAttachment attachmentWithIdentifier:@"com.connecthings.beaconNotificationImage" URL:placeNotificationImage.getImageURL options:nil error:nil];
        notificationContent.attachments=@[attachement1];
    }

    return notificationContent;
}

- (UILocalNotification * _Nonnull)generateNotificationForIOS9AndMinusWithPlaceNotificationImage:(PlaceNotificationImage * _Nonnull)placeNotificationImage {
    NSLog(@"create notification from app delegate");
    UILocalNotification *notification = [[UILocalNotification alloc]init];

    AdtagPlaceNotification *placeNotification = [placeNotificationImage getPlaceNotification];

    if ([placeNotification getDescription].length <= 0) {
        [notification setAlertBody:[placeNotification getTitle]];
    } else{
        [notification setAlertBody:[placeNotification getDescription]];
    }

    if (SYSTEM_VERSION_GREATER_THAN(@"7.99") && [placeNotification getTitle].length > 0) {
        [notification setAlertTitle:[placeNotification getTitle]];
    }

    return notification;
}
func generateNotificationForIOS10AndPlus(placeNotificationImage: PlaceNotificationImage) -> UNMutableNotificationContent {
    let placeNotification = placeNotificationImage.getPlaceNotification()
    let notificationContent: UNMutableNotificationContent = UNMutableNotificationContent()

    notificationContent.title = placeNotification.getTitle()
    if placeNotification.getDescription().isEmpty {
        notificationContent.body = placeNotification.getTitle()
    } else {
        notificationContent.body = placeNotification.getDescription()
    }

    if placeNotificationImage.hasImage() {
        do {
            let notificationId = "com.connecthings.beacon.image"
            if let imageURL = placeNotificationImage.getImageURL() {
                let attachement: UNNotificationAttachment! = try UNNotificationAttachment.init(identifier: notificationId, url: imageURL, options: nil)
                notificationContent.attachments = [attachement]
            }
        } catch _{}
    }
    return notificationContent
}

func generateNotificationForIOS9AndMinus(placeNotificationImage: PlaceNotificationImage) -> UILocalNotification {
    let placeNotification = placeNotificationImage.getPlaceNotification()
    let localNotification: UILocalNotification = UILocalNotification()

    let kLocalNotificationTitle:String! = placeNotification.getTitle()
    let kLocalNotificationMessage:String! = placeNotification.getDescription()

    localNotification.alertTitle = kLocalNotificationTitle
    if kLocalNotificationMessage?.isEmpty == false {
        localNotification.alertBody = kLocalNotificationTitle
    } else {
        localNotification.alertBody = kLocalNotificationMessage
    }

    return localNotification
}

Note:

The PlaceNotificationImage object contains the content associated with the beacon in AdTag, moreover it can also contain the image downloaded thanks to the NotificationTask. To access the content, you can use the method getPlaceNotification() which returns an interface with the following main methods :

  • getTitle(): retrieves the title of the notification
  • getDescription(): retrieves the description of the notification

The SDK possesses an implementation of the PlaceNotification called AdtagPlaceNotification, which contains an AdtagContent object. Through it, you can also base the text of your notification on other AdTag categories & fields of your choice, using the method adtagContent getValueFromCategory.

For example, adtagContent getValueFromCategory:@"LINE" andField:@"DIRECTION" allows you to retrieve the DIRECTION field of the LINE category for a real-time transit schedule use case.

Step 3: Register your MyNotificationBuilder

  • Open the AppDelegate.m file
  • First initialize the SDK
  • Get an instance of the AdtagBeaconManager class and register an instance of our MyNotificationBuilder class thanks to the method registeNotificationBuilder()

Switch to Swift

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [...]
    [[AdtagBeaconManager shared] registerNotificationBuilder: [[MyBeaconNotificationBuilder alloc] init]];
    [...]
    return YES;
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    [...]
    AdtagBeaconManager.shared.registerNotificationBuilder(MyBeaconNotificationBuilder())
    [...]
}

Note:

The AdtagBeaconManager only accepts one NotificationBuilder.

In other words, if you register a new NotificationBuilder, the existing one will be automatically replaced.

Start testing

If your beacon is already emitting, you must stop/restart the emission process in order to simulate a new entry region for your smartphone, and generate a notification.

There are 2 solutions to stop/restart the emission process:

  • You can put the beacon inside a microwave (but don't start it!)
  • You can remove the battery from the beacon (in that case, depending on the model, it can take up to 30 seconds for the beacon to start emitting again after you reinsert the battery)
  1. In Xcode, click on "Play" to launch the installation of the application you have just built on your phone

  2. When the application starts, popups ask for permission to access your phone location, bluetooth & notifications: grant them!

  3. Close your application or leave it running in the background

  4. Remove the beacon from the microwave or reinsert the battery

  5. Wait for a few seconds (maximum 1 minute)

  6. Click on the notification that has appeared on your screen just for fun