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
- Get the SDK
- Integrate the SDK
- Ask for user permissions
- Build & test the app
- Set up an account
- FAQs & Guides
- Advanced features
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
underAccount -> Applications
. It should be kept secret as it uniquely identifies your mobile application.
FAQs & Guides
Usage Guides
- Campaign Demo Guide
- Setting up a virtual beacon
- Getting started with geofencing
- Advantages SDK over API
- SDK battery drain analysis
- Apple iBeacon guide
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.