BeaconService 2.14.0

BeaconService 2.14.0

License Unknown
ReleasedLast Release Aug 2019

Maintained by Cornelius Rabsch, Cornelius Rabsch.



Summary

The Proximity SDK simplifies the integration of beacons, geofences and proximity services into your mobile app. A Proximity DMP application token is required, sign up for free.

Table of contents

Example apps

You can find working XCode demos for Swift and Objective-C in the examples directory.

Get the SDK

Download the latest version from our Github release page. See also the Changelog for an overview.

Using CocoaPod

CocoaPod is an easy to use dependency manager for iOS. If you are new to CocoaPod read the Getting Started Guide.

Add the following line to your Podfile.

pod 'BeaconService', '~> 2.12.3'

You can also use a local pod.

pod 'BeaconService', :git => 'https://github.com/squaremetrics/ios_sdk.git', :tag => '~> 2.13.0'

Install the SDK via:

cmd$ pod update

It's this simple. Keep on reading the integration instructions.

Using the Static Framework

Drag & drop the BeaconService/BeaconService.framework file into your project's folder within XCode. Make sure you select Copy items if needed and Create groups within the add file options menu.

Integrate the SDK

After adding the SDK to your XCode project you need to import the BeaconService/BIBeaconService.h header file and initialize the SDK. Replace YOUR_APP_TOKEN with the application token from the Proximity DMP account (under Account -> Applications). See Account setup.

You have to add the NSLocationAlwaysAndWhenInUseUsageDescription, NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription key in the Info.plist with a short friendly description on why you are using location services. Since iOS 10 you also have to add NSBluetoothPeripheralUsageDescription because beacons will be detected. It's only required for the app submission and will not be shown to the user.

For proximity campaigns and location triggers to work reliable you have to enable Background fetch in your projects Capabilities -> Background Modes to ensure that beacon and geofence data is synched, at most once per day. A notification handler is required as well.

See the permissions section for ways of requesting user permission for location services and notifications.

Using Objective-C

In your AppDelegate.h you have to add the header files and the UserNotifications framework.

#import <BeaconService/BIBeaconService.h>
#import <UserNotifications/UserNotifications.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate>

In your AppDelegate.m you can now initialize the library and add the required callback methods.

#import <BeaconService/BIBeaconService.h>

- (BOOL)application:(UIApplication *)application  
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  

    [BIBeaconService requestAuthorization]; // optional
    [BIBeaconService initWithToken:@"YOUR_APP_TOKEN"];

    if (@available(iOS 10, *)) {
       UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
       center.delegate = self;
    }

	return YES;
}

-(void) userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
    return completionHandler(UNNotificationPresentationOptionAlert);
}

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
    [BIBeaconService handleNotification:notification];
}

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    [BIBeaconService performFetchWithCompletionHandler:completionHandler];
}

Using Swift

For Swift projects an Objective-C bridging header is required which should be linked in the build settings and contain the following lines.

#import "BeaconService/BIBeaconService.h"
#import "BeaconService/BIBeaconServiceConfig.h"

In your AppDelegate you can now initialize the SDK and add the required callback methods.

import UserNotifications

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        BIBeaconService.requestAuthorization() // optional            
        BIBeaconService.initWithToken("YOUR_APP_TOKEN")    

        if #available(iOS 10.0, *) {
            let center = UNUserNotificationCenter.current()
            center.delegate = self
        }

        return true
    }

    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        BIBeaconService.handle(response.notification)
    }

    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        return completionHandler(UNNotificationPresentationOptions.alert)
    }

    func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {        
        BIBeaconService.performFetch(completionHandler: completionHandler)        
    }
}

Permissions

For location services and proximity campaigns to work properly it's required to present permissions popups. This can be fully customized and controlled by the app context, i.e. adding pre-permission popups or delaying permission popups until a certain user event is happening.

As a shortcut for testing you can call BeaconService.requestAuthorization() to trigger the popups.

Location Permission

Make sure you add the NSLocationAlwaysAndWhenInUseUsageDescription, NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription key in the Info.plist with a short friendly description on why you are using location services.

Since iOS 8 it’s required that you ask your users for either "Always" or "When in use" authorization, see Core Location in iOS 8. This is a requirement for beacon and geofence detection to work.

locationManager.requestAlwaysAuthorization()

It's OK to ask first for "When in use" permission and later for the "Always" permission.

It's not required and recommended to enable Location updates within the Background Modes in the project settings. This would also complicate the AppStore approval processes.

Notifications

To receive local notifications a permission is required beginning with iOS 8. See the UserNotifications Framework.

Build & test your app

Build & run the project and check the log if data is received.

[BeaconService] Version 2.8.0
[BeaconService] 10 Services, 1000 Beacons, 2 Regions, 1000 Geofences

You can also check the Live Analytics dashboard (after 1 hour) if user activity has been recognized.

Within XCode you can mock location updates and trigger geofences via XCode > Debug > Simulate Location.

Account setup

  • Sign up for a Proximity DMP Account to access the web and mobile dashboards to manage all beacons, geofences and proximity services.

  • Add nearby beacons and/or geofences in MANAGE for initial testing. For beacons you should select the right vendor and UUID, Major and Minor values.

  • Create a campaign with All Beacons group selected and a notification text. Make sure the scheduling criteria are valid for today and the status is Published.

  • Get your Application Token under Account -> Applications. It should be kept secret as it uniquely identifies your mobile application.

FAQs & Guides

Usage Guides

How to stop the SDK?

To gracefully stop the region monitoring you should always use BeaconService.terminate(), e.g. when a user decides to opt-out of proximity services.

What should be considered when submitting the app to the AppStore?

It's best to proactively communicate why location features are used within the app. You should mention that the Proximity SDK from github.com/squaremetrics/sdks is used for detecting nearby beacons.

Make sure you set NSBluetoothPeripheralUsageDescription since iOS 10.

What are Bluetooth Beacons?

Beacon devices are low-energy Bluetooth transmitters that are easy to setup and that provide a high accuracy for localization within buildings. Despite the ease of use it’s important to make sure the following points are taken care of.

  • Permissions Does you app request the right "Always location authorization"?
  • Bluetooth Do you communicate to your mobile users that enabling Bluetooth is necessary to benefit from beacon functionalities?
  • Beacon Placements Are objects blocking a clear line-of-sight?

Advanced features

Once the SDK is integrated you can use the following functionalities and customize the SDK behavior.

Custom user identifiers

You can pass 2 custom user identifiers to the library to ensure data interoperability with your CRM, analytics or marketing systems. All personal identifiable information (PII) should be hashed.

You have to use the BIBeaconServiceConfig object to set custom identifiers upon initialization.

let config = BIBeaconServiceConfig()
config.setCustomID1(ANONYMOUS_USER_ID)
config.setCustomID2(HASHED_EMAIL)
BIBeaconService.initWithToken(API_TOKEN, andConfig: config)

By default the identifier for advertising on iOS (IDFA) is collected if the AdSupport.framework is linked to your application. This framework is only allowed for apps displaying advertising or for retargeting, otherwise it's a common reason for AppStore rejections.

Callbacks with meta data

The SDK broadcasts by default entry, exit and update events for beacon and geofencer zones via the NSNotificationCenter. Update events are defined by proximity changes between immediate, near, far and rough distance changes +/- 10m.

Just add an observer with these notification names.

*BeaconServiceRegionEnter*
*BeaconServiceRegionUpdate*
*BeaconServiceRegionExit*

*GeofenceServiceRegionEnter*
*GeofenceServiceRegionExit*

The userInfo dictionary of the notifications include for beacons BeaconID, proximity UUID, major, minor, proximity and source. For geofences it's GeofenceID, latitude, longitude, radius and source.

Custom meta data (e.g. internal venue or zone IDs) can be added in the web panel with key=value pairs for beacons and geofences.

class ViewController: UIViewController {

	let kEnterBeacon = Notification.Name("BeaconServiceRegionEnter")
	let kUpdateBeacon = Notification.Name("BeaconServiceRegionUpdate")
	let kExitBeacon = Notification.Name("BeaconServiceRegionExit")
	let kEnterGeofence = Notification.Name("GeofenceServiceRegionEnter")
	let kExitGeofence = Notification.Name("GeofenceServiceRegionExit")

	override func viewDidLoad() {
	    super.viewDidLoad()        

	    for name in [kEnterBeacon,kUpdateBeacon,kExitBeacon,kEnterGeofence,kExitGeofence] {
	        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.didReceiveNotification(notification:)), name: name, object: nil)
	    }
	}

	@objc func didReceiveNotification(notification: NSNotification) {
	    print("userInfo: %@", notification.userInfo!)
	}
}

Foreground notifications

To receive notifications when the app is open userNotificationCenter:willPresentNotification:withCompletionHandler: has to be implemented in the AppDelegate :

-(void) userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
    return completionHandler(UNNotificationPresentationOptionAlert);
}

Rich notifications

To receive notifications with images it is needed to specify the image as an action in your campaign settings. We recommend using the following dimensions:

iOS

Maximum possible dimensions are 1,038 pixels x 1,038 pixels

Android

Keep images between a minimum of 800 and maximum of 1,038 pixels

Custom notifications

Similar to proximity event callbacks campaign events are broadcasted without any forced notifications. The BeaconServiceCampaignNotification event contains all your custom meta data that has been entered on the Campaign detail page in the web portal, the SDK automatically caches your specified campaign image so you can directly use it as a UNNotificationAttachment object e.g.:

userInfo = {
    source = "com.beaconinside";
    title = "ACME Shop";
    message = "Welcome at ACME.";
    posID = 12345;
    Key_23423 = "asdfa asdfasdf a dsfas\U00d6;ad -% @2";
    imageURL = "file://";    
    notificationID = 5763263606292480;
    triggeredAt = "2017-08-05T08:45:43+02:00";
}}

The events are broadcasted in background and foreground states, so make sure the app context is loaded properly.

It's required to send a conversion event when a user clicks on a notification, a button or some displayed banner. This way you receive detailed campaign and conversion analytics. The required parameters are part of the userInfo dictionary.

+ (void)sendConversion:(NSString*)notificationID triggeredAt:(NSString*)at;
if notification.name == Notification.Name("BeaconServiceCampaignNotification"),
    let notificationID = userInfo["notificationID"] as? String,
    let at = userInfo["triggeredAt"] as? String {

    BIBeaconService.sendConversion(notificationID, triggeredAt: at)
}

Webhooks

In the web panel you can set up webhooks to get server-side user interaction events in near real-time. This feature is enabled by default.

Access the API

All data can be accessed via server-side APIs. Take a look at the Developer Hub for the public Manager and Analytics API reference.

Support

Just drop us a message if there are any issues or questions.

License

Copyright (c) 2014-2019 Square Metrics GmbH. All rights reserved.