1. Introduction

Thank you for your interest in the Plot plugin. This document gives an overview of the functionality provided, a convenient manual for easy integration within your app and a detailed list of all provided API calls. We hope you will enjoy the benefits provided by our product.

If you are still in need of assistance after reading this documentation please turn to Stack Overflow and post your question mentioning 'Plot Projects', we monitor new incoming questions and try to answer them as soon as possible.

This document contains a high level description of how the plugin works for iOS and Android. Furthermore, this document describes how the plugin can be integrated into your project. It also describes how you can manage your location based notifications through our Dashboard API. We also provide a graphical interface to manage your notifications.

Back To Top

1.1 Overview

The Plot systems works with geofences and notifications. Geofences represent physical locations. They have, amongst other properties, a name, coordinate and a radius. Geofences can have zero or more notifications. Notifications can have time spans associated with them. If this is the case the notification is only presented when the current time falls within one of the time spans provided. If a time span consists of only a start time, it will be active from this date. If only an end time is provided it will be active before this time. Notifications have a message that is presented to the user when they are within the Geofence. By default the radius is 200m or 220 yards. Notifications can optionally be intercepted by the app to either alter or filter them with the Notification Filter. This can be used for segmentation or personalization purposes. If the user opens the notification, meta data associated with it is passed to your app so that it can react appropriately. Each notification will be presented to the user only once.

Notifications entered into the Plot system will take some time to propagate to devices. The Plot client library will utilize its resources as efficiently as possible. This means that it will increase or decrease it’s location update frequency according to a user’s behavior and other circumstances. Plot will remain active as long as possible while maintaining a very low energy consumption footprint. Expected location accuracy in urban areas will be approximately 60m (65 yards) without making use of GPS.

The plugin is optimized for use on foot. However it is also very likely to work when cycling or slowly driving in a car. When the device is plugged in for charging it will be more likely to work in scenarios like driving on the highway and such because power consumption is then no longer an issue.

Back To Top

1.2 Feature overview

As described in this chapter, Plot offers a vast amount of features. Below is a table in which you can see what features are supported per platform or framework.

Features Android iOS Appcelerator (Titanium) PhoneGap / Cordova / Ionic Xamarin
Basic features[1]
Beacons
Geotriggers [2]
Notification handler
Notification filter [3]
Geotrigger handler
Segmentation
Retrieve cached notifications
Retrieve sent notifications
QuickSync [4] [4]
Attribution events
Notification events
Advertising identifier
[1] Basic features are geofencing, enter, exit and dwelling notifications, campaigns, resendability, timespans, opening hours and landing pages.
[2] Geotriggers with dwelling minutes are not supported on iOS.
[3] iOS only, Android can be done natively.
[4] For both iOS and Android additional integration steps are needed.

Back To Top

1.3 Implementation considerations

The following optional features can be considered when implementing the Plot plugin. An overview of the support for these and other features can be seen here.

Location Services Permission dialog

Both for iOS and for Android, it is required to ask the user permission first before getting access to the location of the device. By default, the Plot plugin will automatically ask this permission after the initialization method has been called. Starting from plugin version 2.0.0(iOS)/2.1.0(Android) it is possible to disable this functionality and ask the permission yourself. This allows to pick a more logical time to show the opt-in dialog to the user.

The best results are achieved when you first prime the user that the location services permission will be asked. During this process you tell the user that the app wants to make use of the location of the phone and what advantages it brings for the user. When the user agrees to share their location, then you can show the opt-in dialog.

In Android, it is required to ask permission for location services starting from Marshmallow. In older versions the permission will be asked straight away when installing the app. When your app requests permission for the second time, the "Never ask again" checkbox is added to the dialog. If the user checks this, it will no longer be possible to directly ask the user to opt-in for location services. Therefore, it is important to not ask too often for this permission when the user hasn't granted it the first time. When a user changes their mind, he can change their permission settings in the Settings screen.

Starting from iOS 8 there is a distinction between asking permission for location services that can be used when the app is in use and permission for always access to location services. To achieve best results with the plugin, the always permission is required. Starting from iOS 11 the user always has the option to give the When in use permission, not just the Always permission. When a user changes their mind, he can change their permission settings in the Settings app. It is possible to first ask for When in use permission, which then later can be upgraded to Always permission. To get best results, we recommend explaining to the user why the Always permission is needed and what it brings for the user.

Find more about enabling/disabling the opt-in dialog in the Configuration file section.

Cooldown period

To prevent sending too many notifications to a user, the Plot plugin provides a cooldown period. When the cooldown period is set on the plugin, Plot will make sure that at least this amount of time has elapsed between two notifications. This is useful when your application has a lot of location based notifications, but you want to prevent overwhelming your users with notifications. The default is to use no cooldown period.

Find more information about implementing the cooldown period please see the sections iOS reference and Android reference.

You can also set a cooldown period on a single notification, instead of for the entire plugin. This allows notifications to be received multiple times by a user, but not before the cooldown for that specific notification has passed.

Notification filter

Use a notification filter if you want to prevent notifications from being shown or modify notifications before they are shown. A notification filter is a method that is called before the notifications are shown to the user. This can be used to only show notifications that match with the interests of the user or to personalize the notification. On Android it is possible to send rich notifications, for example notifications with a large image. Rich notifications are also available on iOS. The notification filter feature isn't available on the Phonegap plugin and Appcelerator Titanium module.

If a notification is set to landing page, it will bypass the notification filter and just open the attached URI in full view as HTML page.

Find more information about implementing the notification filter please see the sections iOS Notification filtering, Android Notification filtering, Appcelerator Notification filtering and Phonegap Notification filtering.

Notification handler

A notification handler makes it possible to specify what should happen when the user taps on a notification sent by Plot. This for example allows directly opening a view in your app that shows more information about the subject that was shown in the notification.

When no notification handler is specified, it will treat the data attached to the notification as URI and that URI will be opened. If a notification is set to landing page, it will bypass the notification handler and just open the attached URI in full view as HTML page.

Find more information about custom notification handling please see the sections iOS Notification handling, Android Notification handling, Appcelerator Notification handling and Phonegap Notification handling.

Geotrigger handler

A geotrigger handler makes it possible to define your own custom trigger when the device enters a geofence or gets in range of a iBeacon. You can filter geotriggers depending on your own logic, as you would in the notification filter. You can also use the geotrigger handler as a trigger for your own custom events in your app, for example to smoketest your notification filter.

When no geotrigger handler is specified, all geotriggers will be seen as handled by your app.

Find more information about custom geotrigger handling and implementation in the sections iOS Geotrigger handling, Android Geotrigger handling and Appcelerator Geotrigger handling. We have also blogged about it here.

Retrieve cached notification and geotriggers

It is possible to retrieve the list of notifications and geotriggers the Plot library is currently listening to. You can use this to show the user what is near him. This can also be used to see what Plot has loaded for debugging purposes.

For more information about this feature and its implementation, see section iOS Retrieve cached notifications, Android Retrieve cached notifications, Appcelerator Retrieve cached notifications and Phonegap Retrieve cached notifications.

Retrieve sent notifications and geotriggers

The plugin keeps a list of all the notifications and geotriggers that have been sent. You can retrieve these separately from the plugin to use in your app, for example to show a list of all the interesting the locations the user has passed since the last time he opened the app.

For more information about this feature and its implementation, see section iOS List sent notifications and geotriggers, Android List sent notifications and geotriggers, Appcelerator List sent notifications and geotriggers and PhoneGap List sent notifications and geotriggers.

QuickSync

Our QuickSync feature is an improved way to synchronise your app users' devices with our server. Our default synchronisation lets a device poll for new notifications or geofence every once in a while. This means that after create a notification it can take some time until you receive the notification when testing.

With Quicksync, this issue is resolved because after creating a notification it will get sent to all your users' devices immediately. In order to enable this feature some additional steps are needed, we have written an integration guide for iOS and one for Android.

More information about QuickSync can be found in our seperate blog post about this feature.

Notification events

You can use the notification events to connect the plugin with your own analytics. Our plugin provides notification events for every notification shown to the user, and for every time a notification is tapped.

For more information about this feature and its implementation, see section iOS notification events and Android notification events.

Advertising identifier for custom reporting

The Plot Plugin makes it possible to offer better targeted advertisements and improved segmentation by using the user’s advertising identifier. This identifier can be used in custom reports, which we offer for Gold plans and up.

The advertising identifier can be set in the Plot Plugin from version 1.10.0 and up. In Android this functionality is shipped as part of Google Play Services since version 4.0 and in iOS this is available since version 6.

It is possible for end-users, both on Android and iOS, to opt-out from the advertising identifier. In Android the user this is done in the Google Settings app. In iOS this setting is available through the device settings.

Contact us for the possibilities and how to set the custom reporting up. For technical information about this feature's implementation, see iOS library reference and Android library reference.

Back To Top

1.4 Configuration File

Plot allows configuration of your plugin through a plotconfig.json file placed in your project. The folder for this file depends on your platform (see integration guides).

The configuration file should contain a json object, which may contain the the properties as described below.

All platforms

The configuration file should contain your public token of your app, you can set it by adding the property publicToken and setting its value to it. You can find this token in the Plot Projects Dashboard. This property is required inside the configuration file.

You can also define whether or not Plot should automatically enable when an init method is called for the first time. It will remember calls to enable() or disable(). This property is not required, default is true.

An example plotconfig.json could look like this:

{
  "publicToken": "REPLACE_ME",
  "enableOnFirstRun": true
}

Android plugin configuration

The configuration file can be extended with some additional properties for Android. It is possible to change the icon of the notification. When no icon is provided it will fallback to the app icon. When your app targets Lollipop, it will only use the alpha channel of the image.

You can set the icon by adding the property notificationSmallIcon to the plotconfig.json. The value of the property should be a drawable resource of 24x24dp.

It is also possible to set the accent color of the icon with the property notificationAccentColor. The value of the property should be a color resource (e.g. red) or a color in hexadecimal format (e.g. #01579B). The accent color is only shown on Android Lollipop or newer.

Starting from API level 23 it is required to first request permission from the user before location services can be used. Plot will automatically request this permission when it is enabled for the first time. When declined it will ask again after the specified number of days.

Since plugin version 2.1.0, it is possible to disable the automatic location services opt-in dialog that is shown. Set automaticallyAskLocationPermission to false to disable this opt-in dialog.

Since plugin version 1.11.1 you can customize the behavior by adding the property askPermissionAgainAfterDays and setting its value to the number of days you want to ask again for permission. Set it to -1 to disable follow up attempts after the user declines. The property is optional and defaults to 1. When automaticallyAskLocationPermission is set to false, this option doesn't do anything.

An example plotconfig.json could look like this:

{
  "publicToken": "REPLACE_ME",
  "enableOnFirstRun": true,
  "notificationSmallIcon": "ic_mood_white_24dp",
  "notificationAccentColor": "#01579B",
  "automaticallyAskLocationPermission": true,
  "askPermissionAgainAfterDays": 3
}

iOS plugin configuration

Since version 1.10.3 of our plugin we allow limiting the number of regions that can be monitored at once (iOS has a maximum of 20), so that another library using beacon or geofence regions can be used together with us. The other library would also have to use a similar setup by limiting their usage of the monitored regions.

You can set the maximum regions monitored by Plot by adding the property maxRegionsMonitored to the plotconfig.json. The value of the property should be an integer between 5 and 20.

Since plugin version 2.0.0, it is possible to disable the automatic location services opt-in dialog that is shown. Set automaticallyAskLocationPermission to false to disable this opt-in dialog.

An example plotconfig.json could look like this:

{
  "publicToken": "REPLACE_ME",
  "enableOnFirstRun": true,
  "maxRegionsMonitored": 10,
  "automaticallyAskLocationPermission": true
}

Back To Top

1.5 Frameworks

Plot is offering support for using Plot in PhoneGap / Cordova / Ionic, Appcelerator (Titanium) and Xamarin.

The PhoneGap / Cordova / Ionic plugin is available from: https://github.com/Plotprojects/plot-phonegap-plugin We have included an integration guide and we have blogged about the development of this plugin for iOS and for Android.

The Appcelerator module is available from the Marketplace: Plot: Location Based Notifications Module and the source code is available on GitHub. We have blogged about how to use this here.

The Xamarin plugin is available at https://github.com/Plotprojects/plot-xamarin-plugin We have included documentation about the plugin in the readme file. There is also a step-by-step integration guide

All frameworks are also described in detail in this documentation. See the navigation menu to go to PhoneGap, Appcelerator or Xamarin. A full overview of the supported features can be found here.

Back To Top

1.6 Testing integration of Plot

Because Plot is optimized for energy efficiency, testing your integration of Plot sometimes yields unexpected results even though the integration has been done correctly. Normal use cases aren't strongly affected by these problems. When you update the notifications in our dashboard or using our API then these changes aren't directly in affect on devices. Plot caches the notifications in the device, so it doesn't have to make contact with our servers often. It can take a couple of hours before the devices can start sending out these notifications to your users. Also when the location of the device cannot be accurately determined, no notifications can be sent.

Plot yields the best result when moving, not when staying stationary on one place. A way to test it is working correctly and stays working correctly is to create a new notification at your office that will become active the next day, so you will receive the notification the next day when you arrive at your office.

When notifications don't have a cooldown period, each notification can only be received once. If you want to receive a notification again for testing, you can remove the app data so it becomes a new installation again and all notifications can be received again. This can be done by removing the app and installing it again.

We have a more extensive guide written on how to test Plot for both Android and iOS.

Back To Top

1.7 iBeacon support

iBeacon notifications are supported for both our iOS plugin (from version 1.5.5 and up) and our Android plugin (from version 1.7.0 and up). A full overview of the supported features can be found here.

iBeacons allow you to send location based notifications to users within smaller ranges than geofences allow, for instance inside a store or other kind of buildings.

Read all documentation regarding our iBeacon support here.

Back To Top

1.8 Dwelling and exit notifications

Since version 1.6.0 we support dwelling notifications and exit notifications. This allows you to send a notification when a user has been in the geofence for a specified amount of time or when the user exits the geofence. By default the notification is sent when a user enters the geofence, but this can be changed in our Dashboard under the "Advanced settings" of a notification. For dwelling notifications an amount of time must be specified that a user must remain in the geofence before receiving the notification. This must be between 5 minutes and 12 hours.

Dwelling and exit notifications are also available for iBeacons and are supported on all platforms and frameworks. Due to restrictions in iOS, dwelling geotriggers are not available for that platform. A full overview of the supported features can be found here.

Back To Top

1.9 Segmentation

Location based notifications are already more relevant than push notifications, but to further improve the relevancy of your notifications you can segment your users. This feature is introduced in version 1.10.0 of our plugin. The segmentation feature allows you to limit specific notifications to specific groups of users. This prevents your end users from receiving notifications that aren't relevant for them.

Segmentation is currently supported for Android, iOS, Appcelerator (Titanium) and Phonegap/Cordova/Ionic, a full overview of the supported features can be found here.

More information about segmentation is available in the segmentation guide.

Back To Top

1.10 Geotriggers

Since version 1.10.0 we support geotriggers. A geotrigger is used to see if users enter or exit a geofence. It works the same as a geofence notification, but does not display anything on the device of the user. You can use the geotrigger handler to call custom code inside your app, which allows you to create events depending on your app users location. Geotriggers are also available for iBeacons.

Please note that due to restrictions in iOS dwelling time is not supported for geotriggers, we do support it for Android. A full overview of the supported features can be found here.

We have blogged about how to use the geotrigger handler here.

Data Campaigns

Data campaigns is our new term to describe campaigns that are not used to show Notifications to the users’ devices as opposed to Notification campaigns. They only gather insights concerning the user’s location activity.

Data campaigns include two sub-types of campaigns. Those are Listening campaigns and Attribution campaigns.

Listening campaigns represent the previously called Geotrigger campaigns. More information about the Attribution campaigns can be found in the Attribution Campaign Guide.

Back To Top

2. iOS Plugin

iOS is the mobile operating system used by Apple for both iPhone and iPad. This chapter will elaborate on the way our plugin can be used when creating an app for iOS.

Back To Top

2.1 Integration

Update October 26th 2017: We have updated this guide after the release of version 2.0.2 of our iOS plugin.

This guide shows how to verify the iOS integration of the Plot plugin

  1. Integration with Cocoapods, using Swift
  2. Integration with Cocoapods, using Objective C
  3. Integration without Cocoapods, using Swift
  4. Integration without Cocoapods, using Objective C

 

1. Integration with Cocoapods, using Swift

To use the library in an iOS application, a few steps must be performed. The first steps differ based on whether or not you're using Cocoapods. The Cocoapods integration is the easiest, but if you want to add the library yourself to the project that is fine too.

 

Step 1: Update your podfile

If you are using CocoaPods, sign up and just add the following line to your Podfile to integrate the library into your IOS application.

Add the following to your podfile:

use_frameworks!
pod 'PlotPlugin'

 

Step 2: Run pod install

Run

pod install

to let Cocoapods download our library and setup the new project structure.

 

Step 3: Add usage description

Add in "Custom iOS Target Properties" under "Info" the keys from the table below. Each value must be a message for the user describing why your app uses the location of the device. For example: "Your location is used to instantly inform you when you are near a location that is interesting to you."

Required key Description shown in XCode
NSLocationAlwaysUsageDescription Privacy - Location Always Usage Description
NSLocationWhenInUseUsageDescription Privacy - Location When In Use Usage Description
NSLocationAlwaysAndWhenInUseUsageDescription* Privacy - Location Always and When In Use Usage Description
* this key is added in XCode 9. If you're using XCode 8, you can add the key yourself.

This text is shown when permission to use the location of the device is requested. Note that for the app to be accepted in the App Store, the description why the app needs location services must be clear to the end user.

 

Step 4: Add configuration file

You can configure Plot through the configuration file. You can find an example config file and your public token on the Developer page on our dashboard.

Add this file as plotconfig.json in the root folder.

{
  "publicToken": "REPLACE_ME",
  "enableOnFirstRun": true
}

 

Step 5: Add PlotDelegate

Add PlotDelegate to the implemented protocols of your AppDelegate.

@UIApplicationMain
class AppDelegate: UIResponder,
                   UIApplicationDelegate,
                   PlotDelegate

 

Step 6: Implement AppDelegate

In your AppDelegate call PlotDebug.initialize(launchOptions: launchOptions, delegate: self) in func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool. The initialize method must be called before the end of that method.

Plot is enabled by default on the first run. If you don't want Plot enabled by default, you can set the enableOnFirstRun property in plotconfig.json to false if Plot shouldn't be enabled by default. If you don't want the permission dialogs to appear straight away when it initializes, then you can add the automaticallyAskLocationPermission property and the automaticallyAskNotificationPermission property in plotconfig.json to false. When setting those properties to false, you become responsible yourself for asking the user for location services and notification permissions.

import PlotProjects

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

  //PlotDebug enables extra debug logging
  //which makes it easier to understand
  //what is going on
  //
  //Replace PlotDebug with PlotRelease
  //to disable debug logging
  PlotDebug.initialize(launchOptions: launchOptions, delegate: self)

  //This method must be called before the end of application(,didFinishLaunchingWithOptions)


  return true
}
...

Now the Plot Projects library should be ready for use! Create a notification in the dashboard at your current location and launch your app to verify it's working.

An example configuration file and your public token can be found on the Download page on our dashboard. You are now ready to receive your first notification. Need more help during testing, look at the test guide.

For more details, look at the testing section of the documentation.

 

2. Integration with Cocoapods, using Objective C

To use the library in an iOS application, a few steps must be performed. The first steps differ based on whether or not you're using Cocoapods. The Cocoapods integration is the easiest, but if you want to add the library yourself to the project that is fine too.

 

Step 1: Update your podfile

If you are using CocoaPods, sign up and just add the following line to your Podfile to integrate the library into your IOS application.

Add the following to your podfile:

use_frameworks!
pod 'PlotPlugin'

 

Step 2: Run pod install

Run

pod install

to let Cocoapods download our library and setup the new project structure.

 

Step 3: Add usage description

Add in "Custom iOS Target Properties" under "Info" the keys from the table below. Each value must be a message for the user describing why your app uses the location of the device. For example: "Your location is used to instantly inform you when you are near a location that is interesting to you."

Required key Description shown in XCode
NSLocationAlwaysUsageDescription Privacy - Location Always Usage Description
NSLocationWhenInUseUsageDescription Privacy - Location When In Use Usage Description
NSLocationAlwaysAndWhenInUseUsageDescription* Privacy - Location Always and When In Use Usage Description
* this key is added in XCode 9. If you're using XCode 8, you can add the key yourself.

This text is shown when permission to use the location of the device is requested. Note that for the app to be accepted in the App Store, the description why the app needs location services must be clear to the end user.

 

Step 4: Add configuration file

You can configure Plot through the configuration file. You can find an example config file and your public token on the Developer page on our dashboard.

Add this file as plotconfig.json in the root folder.

{
  "publicToken": "REPLACE_ME",
  "enableOnFirstRun": true
}

 

Step 5: Add PlotDelegate

Add PlotDelegate to the implemented protocols of your AppDelegate in the header (.h) file.

#import <PlotProjects/Plot.h>

@interface AppDelegate : UIResponder
  <UIApplicationDelegate, PlotDelegate>

 

Step 6: Implement AppDelegate

In the implementation file (.m) of your AppDelegate call [Plot initializeWithLaunchOptions:launchOptions delegate:self] in application:didFinishLaunchingWithOptions:. The initialize method must be called before the end of that method.

Plot is enabled by default on the first run. If you don't want Plot enabled by default, you can set the enableOnFirstRun property in plotconfig.json to false if Plot shouldn't be enabled by default. If you don't want the permission dialogs to appear straight away when it initializes, then you can add the automaticallyAskLocationPermission property and the automaticallyAskNotificationPermission property in plotconfig.json to false. When setting those properties to false, you become responsible yourself for asking the user for location services and notification permissions.

@implementation AppDelegate

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

  //initializes the Plot library:
  [Plot initializeWithLaunchOptions:launchOptions delegate:self];
  //This method must be called before the end of the application:didFinishLaunchingWithOptions: method

  return YES;
}
...

Now the Plot Projects library should be ready for use! Create a notification in the dashboard at your current location and launch your app to verify it's working.

An example configuration file and your public token can be found on the Download page on our dashboard. You are now ready to receive your first notification. Need more help during testing, look at the test guide.

For more details, look at the testing section of the documentation.

 

3. Integration without Cocoapods, using Swift

To use the library in an iOS application, a few steps must be performed. The first steps differ based on whether or not you're using Cocoapods. The Cocoapods integration is the easiest, but if you want to add the library yourself to the project that is fine too.

 

Step 1: Get The Library

Once you log in to our dashboard, download the library under the "Developer Tools" page.

 

Step 2: Add PlotProjects.framework and other dependencies to your project

Extract the zip file and copy the PlotProjects.framework file to your project.

In the target settings add the following libraries in "Link Binary with libraries" under "Build phases"

  • PlotProjects.framework
  • libsqlite3.tbd
  • CoreLocation.framework
  • MessageUI.framework
  • UserNotifications.framework

You also need to add PlotProjects.framework to Embedded Binaries as well

 

Step 3: Add usage description

Add in "Custom iOS Target Properties" under "Info" the keys from the table below. Each value must be a message for the user describing why your app uses the location of the device. For example: "Your location is used to instantly inform you when you are near a location that is interesting to you."

Required key Description shown in XCode
NSLocationAlwaysUsageDescription Privacy - Location Always Usage Description
NSLocationWhenInUseUsageDescription Privacy - Location When In Use Usage Description
NSLocationAlwaysAndWhenInUseUsageDescription* Privacy - Location Always and When In Use Usage Description
* this key is added in XCode 9. If you're using XCode 8, you can add the key yourself.

This text is shown when permission to use the location of the device is requested. Note that for the app to be accepted in the App Store, the description why the app needs location services must be clear to the end user.

 

Step 4: Add configuration file

You can configure Plot through the configuration file. You can find an example config file and your public token on the Developer page on our dashboard.

Add this file as plotconfig.json in the root folder.

{
  "publicToken": "REPLACE_ME",
  "enableOnFirstRun": true
}

 

Step 5: Add PlotDelegate

Add PlotDelegate to the implemented protocols of your AppDelegate.

@UIApplicationMain
class AppDelegate: UIResponder,
                   UIApplicationDelegate,
                   PlotDelegate

 

Step 6: Implement AppDelegate

In your AppDelegate call PlotDebug.initialize(launchOptions: launchOptions, delegate: self) in func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool. The initialize method must be called before the end of that method.

Plot is enabled by default on the first run. If you don't want Plot enabled by default, you can set the enableOnFirstRun property in plotconfig.json to false if Plot shouldn't be enabled by default. If you don't want the permission dialogs to appear straight away when it initializes, then you can add the automaticallyAskLocationPermission property and the automaticallyAskNotificationPermission property in plotconfig.json to false. When setting those properties to false, you become responsible yourself for asking the user for location services and notification permissions.

import PlotProjects

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

  //PlotDebug enables extra debug logging
  //which makes it easier to understand
  //what is going on
  //
  //Replace PlotDebug with PlotRelease
  //to disable debug logging
  PlotDebug.initialize(launchOptions: launchOptions, delegate: self)

  //This method must be called before the end of application(,didFinishLaunchingWithOptions)


  return true
}
...

Now the Plot Projects library should be ready for use! Create a notification in the dashboard at your current location and launch your app to verify it's working.

An example configuration file and your public token can be found on the Download page on our dashboard. You are now ready to receive your first notification. Need more help during testing, look at the test guide.

For more details, look at the testing section of the documentation.

 

4. Integration without Cocoapods, using Objective C

To use the library in an iOS application, a few steps must be performed. The first steps differ based on whether or not you're using Cocoapods. The Cocoapods integration is the easiest, but if you want to add the library yourself to the project that is fine too.

 

Step 1: Get The Library

Once you log in to our dashboard, download the library under the "Developer Tools" page.

 

Step 2: Add PlotProjects.framework and other dependencies to your project

Extract the zip file and copy the PlotProjects.framework file to your project.

In the target settings add the following libraries in "Link Binary with libraries" under "Build phases"

  • PlotProjects.framework
  • libsqlite3.tbd
  • CoreLocation.framework
  • MessageUI.framework
  • UserNotifications.framework

You also need to add PlotProjects.framework to Embedded Binaries as well

 

Step 3: Add usage description

Add in "Custom iOS Target Properties" under "Info" the keys from the table below. Each value must be a message for the user describing why your app uses the location of the device. For example: "Your location is used to instantly inform you when you are near a location that is interesting to you."

Required key Description shown in XCode
NSLocationAlwaysUsageDescription Privacy - Location Always Usage Description
NSLocationWhenInUseUsageDescription Privacy - Location When In Use Usage Description
NSLocationAlwaysAndWhenInUseUsageDescription* Privacy - Location Always and When In Use Usage Description
* this key is added in XCode 9. If you're using XCode 8, you can add the key yourself.

This text is shown when permission to use the location of the device is requested. Note that for the app to be accepted in the App Store, the description why the app needs location services must be clear to the end user.

 

Step 4: Add configuration file

You can configure Plot through the configuration file. You can find an example config file and your public token on the Developer page on our dashboard.

Add this file as plotconfig.json in the root folder.

{
  "publicToken": "REPLACE_ME",
  "enableOnFirstRun": true
}

 

Step 5: Add PlotDelegate

Add PlotDelegate to the implemented protocols of your AppDelegate in the header (.h) file.

#import <PlotProjects/Plot.h>

@interface AppDelegate : UIResponder
  <UIApplicationDelegate, PlotDelegate>

 

Step 6: Implement AppDelegate

In the implementation file (.m) of your AppDelegate call [Plot initializeWithLaunchOptions:launchOptions delegate:self] in application:didFinishLaunchingWithOptions:. The initialize method must be called before the end of that method.

Plot is enabled by default on the first run. If you don't want Plot enabled by default, you can set the enableOnFirstRun property in plotconfig.json to false if Plot shouldn't be enabled by default. If you don't want the permission dialogs to appear straight away when it initializes, then you can add the automaticallyAskLocationPermission property and the automaticallyAskNotificationPermission property in plotconfig.json to false. When setting those properties to false, you become responsible yourself for asking the user for location services and notification permissions.

@implementation AppDelegate

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

  //initializes the Plot library:
  [Plot initializeWithLaunchOptions:launchOptions delegate:self];
  //This method must be called before the end of the application:didFinishLaunchingWithOptions: method

  return YES;
}
...

Now the Plot Projects library should be ready for use! Create a notification in the dashboard at your current location and launch your app to verify it's working.

An example configuration file and your public token can be found on the Download page on our dashboard. You are now ready to receive your first notification. Need more help during testing, look at the test guide.

For more details, look at the testing section of the documentation.

Back To Top

2.2 Test Guide

Update October 26th 2017: We have updated this guide after the release of version 2.0.2 of our iOS plugin.

This guide shows how to verify the iOS integration of the Plot plugin

  1. Receiving Of Notifications Test
  2. Debug mode and log messages
  3. Sending the Debug Log via e-mail
  4. Location testing using emulator
  5. Test Energy Efficiency
  6. Wrap up

 

1. Receiving Of Notifications Test

After completing the basic integration of the Plot Projects SDK you need to test it. You verify whether the Plot plugin is integrated properly by receiving a location based notification. When you have receive a notification, you know the basic integration is successful.

How to test the basic integration of the Plot Projects iOS SDK in your app:

  1. Ensure your test app is connected to your sandbox environment in Plot Projects to prevent your end-users from receiving test notifications. If you don't have a Sandbox environment yet, you can create one by clicking on your app in the Plot Dashboard > Manage apps and plans > Create new app.
  2. Install your app on your phone. If it is already installed, then remove the app and reinstall it, so you can start from a clean slate.
  3. Log in into the Plot Projects dashboard
  4. When in your Sandbox app, go to the Notification Campaigns screen by clicking on the corresponding menu item. At the bottom right, you can create a new Notification Campaign.
  5. Give the campaign a name and a message. You can ignore the fields on the Advanced Settings screen.
  6. Select the action "Open app". If you don't have a geofence yet at your location, you can create one now on this screen. Place the geofence at the location where you're currently are. The geofence radius should be kept at 200 meters.
  7. Select in the "Users should receive notifications" section the option "More than once" and save your campaign.
  8. Note that you don't receive this notification on your device immediately. The Plot Projects SDK only connects to our backend periodically to update its cached campaigns. Every few hours or when the device has moved significantly. Opening or closing the app in this period doesn't influence this. hen a new notification has been added it takes a while before that notification is downloaded and can be received by you. If you don't want to wait this long you have the following options:
    • You can set up the Plot Projects feature Quicksync, which allows you to instantly send new campaigns to all your app users. See our Quicksync integration guide how to set this up.
    • Turn on and off flight mode. Note that, this workaround only works once per 10 minutes.
    • Reinstall the app
  9. If you did not receive your test notification please use this checklist.

Notice: When a notification has been received, it won't be resent until you properly leave the geofence and re-enter it. Reinstalling the app allows you to receive a notification again.

 

2. Debug mode and log messages

To aid you in debugging, Plot provides diagnostic messages in the console. These messages are only enabled when Plot is compiled with a debug configuration. The messages show which notifications were considered for showing and how far Plot thinks you are from these notifications. This makes it clearer why a notification has been or hasn't been shown.

XCode's console shows these debugging messages.

Example debug log output

When enabling Plot you see the following log message

2017-09-18 16:34:51.460 - Plot enabled

After the Plot plugin is enabled, it downloads the notifications from the server. It shows the total number of notifications and the notifications that have been loaded. You can use the following message to ensure the right notifications are loaded.

2017-09-18 16:34:54.349 - Loaded new notifications (1 total)
2017-09-18 16:34:54.349 - Notification: a9f242b4be384923896168dc2c134585 - Wiki Notificati...

Once the notifications are loaded, Plot matches these. It shows the loaded notifications and the distance to these notifications in meters. Where the distance is smaller than the match range, a notification "matches" and is sent to the notification filter or geotrigger handler (if you have one or both defined) so that it's processed by the logic that you defined.

2017-09-18 16:34:54.383 - Distance to a9f242b4be384923896168dc2c134585 - Wiki Notificati...: 4018 (range: 200)

When there is at least one notification or geotrigger sent to the notification filter/geotrigger handler, then you see the following line with the number of matching notifications. The example below uses a geotrigger handler. When you don't have a notification filter/geotrigger handler, this step is skipped.

2017-09-18 11:27:25.086 - Offered geotriggers to the geotrigger handler (1 total)

Once notification filter/geotrigger handler completes, then the following log message appears. It shows how many notifications passed through the notification filter and then shows these notifications. These notifications should then appear in the notification area.

2017-09-18 11:27:25.096 - Geotrigger handler completed (1 passed)
2017-09-18 11:27:25.187 - handled: 3fda60abc4fa4472986fb5e108989991;a01a770391134f55be0ce90b88dc13f2 - Plot..

The debug output also includes useful info about:

When the plugin detects a new updates

2017-09-18 17:54:55 - Acquired location: 52.344271,4.916536 (accuracy 65 meter)

Notifications loaded through QuickSync (Integration guide), denoted by the keywords "from push"

2017-09-18 18:00:08 - Loaded new notifications from push (6 total)

Shown notifications

2017-09-18 17:12:48 - Showing notification: da13094b56d0482298d5fba912ad8cbd - Welcome

Sent geotriggers

2017-09-18 17:12:48 - Geotrigger sent: 605ef54c3dd94a3bb87cee0c4d70df98;27d74b87987943d1b93d4dea3ad04081 - test geotrigger...

Region status, e.g "User first has to leave area", which means that to trigger the region the user has to leave and reenter the area, or "Dwell initiated", which means that the dwell timer has started

2017-09-18 17:54:55 - User first has to leave area of 9dee12a6151f4297b366fd82161e1f00;41b1ce9a9f2140ce9512f03b4fafc04b - test

 

3. Sending the Debug Log via mail

You might need to mail the debug log to yourself. With Plot all you have to do is call Plot's provided method, e.g. after a button click event.

Objective-C:

(void)mailDebugLog:(UIViewController*)viewController

Swift:

func mailDebugLog(UIViewController:viewController)

The method will start your mail client so you can send the debug log (a log file generated by plot) to yourself or your nearest developer. Note: this method should only be used when compiling for DEBUG. An example of this can be seen in our demo apps, which you can download from our dashboard.

 

4. Location testing using emulator

Location testing is essential when working with any location based technology and Plot is no exception, however moving to a physical location is not always possible or practical. To deal with this, XCode's device simulator (Getting Started in Simulator) provides a way to emulate a current location. To change a device's current location, click on the custom location option in the Simulator's debug menu as presented in the image below:

After clicking, a window will popup that allows you to input the coordinates of your testing location. The app now behaves as if you were at that specified location and the notifications that you set up previously triggers.

 

5. Test Energy Efficiency

Because Plot keeps receiving the location of your device in the background you must ensure that your application stops doing work in the background. Tasks you need to look out for are timers that are scheduled repeatedly and subscriptions on location services.

Before you start a task ensure that your application is in the foreground. Note, when your app starts it may stay in the background. Don't assume it directly moves to the foreground. To check that your app is in the foreground, or your app starts and will move to the foreground can be done with: application.applicationState != UIApplicationStateBackground. IOS provides notifications which inform you when the app moves to the background, so you can pause the tasks when the app transitions to the background. There's another notification that informs when the application moves back to the foreground.

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(applicationWillResignActive)
                                             name:UIApplicationWillResignActiveNotification
                                           object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(applicationWillEnterForeground)
                                             name:UIApplicationWillEnterForegroundNotification
                                           object:nil];

When your app makes use of MKMapView in a view that is directly loaded when your app starts and has the option "Shows User Location" enabled, then your app starts using GPS when it starts. Even when it starts in the background. You need to enable that option programmatically after the view did appear instead of directly when the view loads.

XCode comes with a tool called Instruments that shows multiple metrics related to power usage. Instruments can be found in the XCode menu behind "Open Developer Tool". The tool you need here is "Energy Log".

It shows among other things how much of the CPU it utilizes and whether GPS is enabled. Keeping GPS enabled in the background really reduces battery life.

An important use case to test is what happens when your application starts in the background. The easiest way to trigger this is to start your app, allow location services and then restart your iPhone. Your app then starts with Plot in the background.

 

6. Wrap up

We have shown you how you can verify that your app can successfully receive notifications regardless of your physical location and how you can verify that your app doesn't consume too much energy when in the background.

We hope that this blogpost clarifies how to properly integrate Plot. If you have problems during one of these steps, you can post your question to StackOverflow.

Back To Top

2.3 Functionality

The plugin targets iOS 6.0 and up. It is binary compatible with iOS 4.3 and 5.x, but the service will not be enabled. When the Plot plugin is initialized by the [Plot initializeWithLaunchOptions:delegate:] call, it checks if it was previously enabled. If the location monitoring service is not running and it was previously enabled by the [Plot enable] call it will (re)enable the location monitoring service. The location monitoring service is also restarted automatically after the device reboots.

The plugin makes use of the region monitoring capabilities provided by iOS and some improvements we have added ourselves. The location of the user will be determined in a way that minimizes battery usage; GPS is almost never used as the service uses Wifi-triangulation. When the user is within the radius of a geofence with a published notification it will present a Local Notification to the user (Local Notifications are faster than Push Notifications and don't require an internet connection). The default distance is 200m (220 yards). Due to hardware restrictions the minimum distance on the iPhone 4 and earlier iPhone models is 400m.

When the app is already running (in the background or in the foreground), the application:didReceiveLocalNotification method of your app is called when the user taps on a notification. When the application is not running, then the app is started and the notification is passed through application:didFinishLaunchingWithOptions:. We provide a default implementation to open a browser with the URL enclosed in the data field of the notification. If the app is running in the foreground our default implementation shows a confirmation dialog first. If you don't want to make use of the default implementation, but want to deal with notifications yourself you'll have to implement plotHandleNotification: of the delegate passed to [Plot initializeWithLaunchOptions:delegate:].

The Plot plugin is optimized for users traveling at low speeds (walking, biking). The geofences and notifications will be synchronized with our back end periodically. Therefore it may take a while before a notification you have added is available on the phone. When traveling at higher speeds or when a phone temporarily cannot determine its location, it is possible that a Location Based Notification is not sent even when a user is inside a geofence. You can however increase the radius of the geofence to increase the chances of the user receiving the notification in this use case.

When the application is compiled in Debug mode, Plot will print extra information about the loaded notifications on the console to aid in debugging.

iBeacon notifications are supported for our iOS plugin (from version 1.5.5 and up). iBeacons allow you to target users within smaller ranges, for instance inside a store or other kind of buildings. You can add iBeacons just like normal geofences in our dashboard. Instead of a latitude and longitude, iBeacons are identified by a proximity UUID, a majorId and a minorId. iBeacon notifications are also passed through the Notification Filter and the Notification Handler as normal notifications from the Plot plugin would. Read all documentation regarding our iBeacon support in Chapter 2: iBeacons.

Back To Top

2.4 Notification handling

When you don't specify a callback for handling notifications, Plot will handle the notifications in the following manner: When a notification is opened, it will treat the data field of the notification as URI and tries to open it.

If you don’t want Plot to handle the notifications, you can handle the notifications yourself. The delegate passed to initializeWithLaunchOptions:delegate: determines what is done after a notification is opened. The delegate has to implement the PlotDelegate protocol. When the method -(void)plotHandleNotification:(UNNotificationRequest*)notification data:(NSString*)action is implemented, the default handler is replaced by this method which will then be called when a notification is opened.

Back To Top

2.5 Notification filtering

When you want to segment your users or want to personalize the notifications, you can use the notification filter. The delegate passed to initializeWithLaunchOptions:delegate: may implement the optional method -(void)plotFilterNotifications:(PlotFilterNotifications*)filterNotifications. When the method is implemented, Plot will send the notifications to this method before showing them on the mobile device. This allows you to prevent notifications from being shown or change the notifications. Please note that due to restrictions in iOS the notification filter for dwelling notifications is called when the user enters the geofence or beacon region and that the returned notifications are only shown when the user remains in the region for the specified amount of time.

The “data” field of a notification allows you to add custom information to a notification in our dashboard that you can access in the plotFilterNotifications: method. Plot doesn’t prescribe a format for this data. You can use plain text, or for example use JSON. You can access it by reading the PlotNotificationDataKey (constant defined in plot.h) from the userInfo dictionary of the UNNotificationRequest.

Make sure to always call showNotifications: at the end of your filtering, even when you have no notifications left. This way our plugin knows you have finished filtering.

//Example for plotFilterNotifications:
-(void)plotFilterNotifications:(PlotFilterNotifications*)filterNotifications {
    NSArray* notifications = filterNotifications.uiNotifications;
    for (UNNotificationRequest* notification in notifications) {

        //alter notification
        //ensure the keys in the userInfo also present in the new object.
        NSString* customMessage = @"Custom message";
        UNMutableNotificationContent* customContent =  [[UNMutableNotificationContent alloc] init];
        customContent.body = customMessage;
        NSMutableDictionary* userInfo = [notification.content.userInfo mutableCopy];
        customContent.userInfo = userInfo;
        UNNotificationRequest* updatedNotification =  [UNNotificationRequest requestWithIdentifier:notification.identifier content:customContent trigger:notification.trigger];
        [updatedNotifications addObject: updatedNotification];
    }
    // Always call showNotifications at the end of the method
    [filterNotifications showNotifications:updatedNotifications];
}
//Example for plotFilterNotifications creating a rich notification:
    -(void)plotFilterNotifications:(PlotFilterNotifications*)filterNotifications {
    NSArray* notifications = filterNotifications.uiNotifications;
    for (UNNotificationRequest* notification in notifications) {

        NSURL *fileURL = ... //  your media item file url
        NSError *error;

        NSArray* attachments = [NSMutableArray array];
        UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"attachment" URL:imageURL options:nil error:&error]

        // first create your custom content object as in the previous example...

        customContent.attachments = [attachments arrayByAddingObject:attachment];

        //...ensure you update the notification object with the new content as in the previous example
    }
    // Always call showNotifications at the end of the method
    [filterNotifications showNotifications:notifications];
}

You can change all fields of the PlotFilterNotifications object, except the fields that are related to scheduling. That functionality is not supported. For a reference of all fields you can change, you can check the Apple iOS Documentation. In order to implement rich notifications, you need to add each media item (UNNotificationAttachment) to the attachments array present in the UNMutableNotificationContent using the Notification Filter. Similarly to the rich content, to implement the Custom actions feature, you have to resort to the Notification Filter. This feature relies on two classes UNNotificationAction and UNNotificationCategory

When you have enabled the data protection feature of iOS, you have to ensure that the files you read in the filter are readable when the phone is locked. This can for example be done by setting the protection level of these files to None or CompleteUntilFirstUserAuthentication.

We have written a more extensive blog post about this: Using The Notification Filter To Increase Relevance.

Back To Top

2.6 Geotrigger handling

When you want to handle your geotriggers, or use them as trigger events for your own code, you can use the geotrigger handler. The delegate passed to initializeWithPublicKey:launchOptions:delegate: may implement the optional method -(void)plotHandleGeotriggers:(PlotHandleGeotriggers*)geotriggerHandler. When the method is implemented, Plot will send the geotriggers to this method before considering them as handled. This allows you to add custom code that is triggered by entering (or exiting) a geofence or beacon region. Please note that due to restrictions in iOS dwelling time is not supported for geotriggers in iOS.

Make sure to always call markGeotriggersHandled: at the end of your handling, even when you have no geotriggers left. This way our plugin knows you have finished.

//Example for plotHandleGeotriggers:
-(void)plotHandleGeotriggers:(PlotHandleGeotriggers*)geotriggerHandler {
    NSMutableArray* toPass = [[NSMutableArray alloc] init];
    for (PlotGeotrigger* geotrigger in geotriggerHandler.geotriggers) {
        if ([@"pass" isEqualToString:[geotrigger.userInfo objectForKey:PlotGeotriggerDataKey]]) {
            [toPass addObject:geotrigger];
        }
    }
    // Always call markGeotriggersHandled at the end of the method
    [geotriggerHandler markGeotriggersHandled:toPass];
}

You can read all fields from a geotrigger just as you would do that for a notification in the notification filter, most of them can be found in the userInfo. Full reference of keys for this can be found in the library reference.

When you have enabled the data protection feature of iOS, you have to ensure that the files you read in the handler are readable when the phone is locked. This can for example be done by setting the protection level of these files to None or CompleteUntilFirstUserAuthentication.

Back To Top

2.7 Retrieve cached notifications

It is possible to retrieve the list of notifications and geotriggers the Plot library is currently listening to. You can, for example, use this to show the user what is near him. This can also be used to see what Plot has loaded for debugging purposes.

The plugin exposes two method: [Plot loadedNotifications] and [Plot loadedGeotriggers]. Fields like notification message, latitude, longitude, data are available.

When no notifications are loaded an empty list is returned. This could for example be the case when the location of the device is unknown.

Back To Top

2.8 List sent notifications and geotriggers

The library allows you to retrieve the sent notifications and geotriggers using the method [Plot sentNotifications] for notifications and [Plot sentGeotriggers] for geotriggers. The library will retain up to 100 notifications and geotriggers, before the oldest notifications/geotriggers get deleted. When you alter the notification message or the data property, this alteration will also be applied to the notification in the history. The objects returned contain the time the notification or geotrigger was sent and when, if it has, been opened or handled.

It is possible to remove the history of sent notifications and geotriggers yourself by using the [Plot clearSentNotifications] method for notifications and the [Plot clearSentGeotriggers] method for geotriggers.

An use case where this functionality may be useful for is to show a list of the notifications that were sent since the app was last opened. This allows users to see the notifications again, even though they may have dismissed them earlier.

Back To Top

2.9 Notification events

Since plugin version 1.15.0 it is possible to listen to notification events. This feature is especially useful when you want to tie the plugin to your own analytics.

Currently we offer notification events upon showing a notification to the user (sent notification event) and whenever a user taps on a notification (opened notification event).

Whenever such an event happens our plugin will call the appropriate method. The delegate passed to initializeWithLaunchOptions:delegate: may implement the optional methods -(void)plotNotificationSentEvent:(PlotSentNotification*)notification and -(void)plotNotificationOpenedEvent:(PlotSentNotification*)notification to make use of this feature.

See an example implementation below for the notification sent event:

-(void)plotNotificationSentEvent:(PlotSentNotification*)notification {
  NSString* message = [notification.userInfo objectForKey:PlotNotificationMessage];
  NSLog(@"Notification Sent Event: message: %@", message);
  // Make a call to Google Analytics
}

And an example for when a notification is opened:

-(void)plotNotificationOpenedEvent:(PlotSentNotification*)notification {
  NSString* data = [notification.userInfo objectForKey:PlotNotificationDataKey];
  NSLog(@"Notification Opened Event: data: %@", data);
  // Make a call to Google Analytics
}

Back To Top

2.10 App Store description

From the description in the App Store it must be clear for the end user why location services are required. This is something Apple often checks during the review of your app. It is possible to change the description to ensure that it is clear for the end user why location services are required. You can find more information about this in the integration guide.

Back To Top

2.11 Example implementation

This is a minimal example which shows how to integrate Plot. It doesn't have a Notification Filter and uses the default notification handler.

plotconfig.json (you can get one specifically for your app in our dashboard)
{
  "publicToken": "REPLACE_ME",
  "enableOnFirstRun": true
}
AppDelegate.h
#import <UIKit/UIKit.h>
#import <Plot/Plot.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, PlotDelegate>

@property (strong, nonatomic) UIWindow *window;

@end
AppDelegate.m
#import "AppDelegate.h"
#import <Plot/Plot.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //Initializes the Plot library:
    [Plot initializeWithLaunchOptions:launchOptions delegate:self];
    return YES;
}

-(void)plotHandleNotification:(UNNotificationRequest*)notification data:(NSString*)action {
    //Custom handler for notifications. (optional)
    //When you don't want to do a custom action when a notification is opened, then don't implement this method.
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:action]];
}

-(void)plotFilterNotifications:(PlotFilterNotifications*)filterNotifications {
    //Filter for notifications. (optional)
    //When you want to change notifications or prevent sending notifications, then implement this method.

    [filterNotifications showNotifications:filterNotifications.uiNotifications];
}

@end

Back To Top

2.13 iBeacons

What is an iBeacon

An iBeacon is a small wireless device that broadcasts its presence over Bluetooth Low Energy. Apps can register for updates on when the user gets in range of these devices. The phone doesn’t have to pair or set up a connection to detect it’s there.

This allows you to send a notification when a user is near an iBeacon (instead of when a user enters a geofence for geofencing messages). iBeacons allow you to target users within smaller ranges, for instance inside a store or another kind of building. The smaller targeting radius further increases the relevance of the notification.

Starting from version 1.5.5 of our iOS plugin and version 1.7.0 of our Android plugin, iBeacon notifications are supported. Android support for iBeacons in our plugin isn't enabled by default. You have to add an extra library to enable iBeacon support. Instead of when a user enters a geofence you can send a notification when a user comes near an iBeacon. This allows targeting users inside a store, stadium or another kind of building with a smaller match range to increase the relevance of the notification.

When iBeacons are entered in the dashboard then the plugin also monitors the distance to beacon devices to determine whether a notification should be sent to the user. This feature is available on iPhone 4S and newer and for Android devices with Android 4.3 or higher.

Several companies started with selling iBeacons. iBeacons provide the possibility to send location based notifications when the user is inside in a building with a small range instead of a larger region outside. This allows to target your users more precisely.

Characteristics

Each iBeacon has three characteristics that allows to distinguish between multiple iBeacons. The three characteristics are:

proximityUUID:This identifier is the same for all devices you own. You specify the identifier per app in our Dashboard.
majorId:A number that identifies a group of related beacons. For example, you could give all the beacons in the same store the same majorId. It is required to specify this field when you add an iBeacon.
minorId:Another number to distinguish between your iBeacons. For example, you could use this to distinguish between multiple beacons in the same store. You can specify this field when you add an iBeacon to differentiate between beacons with the same majorId. When this field isn't specified, then all beacons that have the specified majorId will trigger a notification.

Some vendors allow to order an iBeacon with these values specified by you, others give iBeacons with default values that you can reprogram using an app they provide. Consult the documentation of the vendor to obtain the characteristics of your iBeacons.

Start sending iBeacon notifications

Before you can receive location based beacon notifications you have to enter the proximityUUID that is shared between all your iBeacons. You can enter the proximityUUID in our dashboard, go to Manage iBeacons and click on Configure iBeacon details. You only have to enter these details once.

After that, iBeacons can be added just like geofences, except that you specify a majorId and optionally a minorId. You can choose between three distances: immediate (less than 1 meter/3 feet), near (around 2 meters/6 feet) or far (around 30 meter/100 feet). Choosing for near or far yields the best result, since immediate is a very short range for the use case of sending notifications.

Testing with iBeacons

You can order iBeacons from various companies or you can turn an iPhone (4S and up) or an iPad into an iBeacon. How to turn your device into an iBeacon you can read here: How to test with an iPhone/iPad. You cannot test the receiving of notifications on an iPhone/iPad that is used as a beacon. So if you want to test with an iPhone/iPad as iBeacon, you need at least two devices.

Note that you can only receive notifications a single time and it may take some time before a notification entered in our dashboard is sent to the device.

A quick way to trigger notifications on your iPhone is to go to your lock screen. iOS will then perform an extra check to determine whether an iBeacon is in range.

Back To Top

2.14 Segmentation

The segmentation feature is introduced in version 1.10.0 of our plugin and further improved by segmentation on campaign history in version 1.12.0. Segmentation allows you to limit specific notifications to specific groups of users. This prevents your end users from receiving notifications that aren't relevant for them.

Two steps are needed when using segmentation, first the segment property and the appropriate value have to be set in the campaign (or notification) in the dashboard. Next to that they have to be set inside your app. When these match, the device will receive the notification.

For each type we expose methods to conveniently set a segment. An example for each type is shown below. When setting a value for an existing property the previous value gets overwritten. Set value to nil to clear the property.

// Set the segment for being a premium member to true.
[Plot setBooleanSegmentationProperty:YES forKey:@"premiumMember"];

// Set the segment for gender to male.
[Plot setStringSegmentationProperty:@"M" forKey:@"gender"];

// Set the segment for year of birth to 1980.
[Plot setIntegerSegmentationProperty:1980 forKey:@"yearOfBirth"];

// Set the segment for money spent to $10.35.
[Plot setDoubleSegmentationProperty:10.35 forKey:@"moneySpent"];

// Set the signup date segment to now.
[Plot setDateSegmentationProperty:[NSDate now] forKey:@"signUp"];

Note: the segmentation key has a limit of 40 characters and the value of 40 characters

More general information about segmentation is available in the segmentation guide.

Back To Top

2.15 QuickSync Integration

 

Guide for Plot version 1.15.3 and lower:

Add QuickSync to receive your notifications immediately. This uses Google Cloud Messaging. This guide assumes you've integrated Plot using Cocoapods. Make sure you already have integrated Plot using the iOS integration guide.

 

STEP 1: Add To Podfile

Add "pod 'Google/CloudMessaging', '1.1.0'" to your Podfile.

pod 'Google/CloudMessaging', '1.1.0'

 

STEP 2: Setup Google Project

Follow the steps at the Google Console to setup your Google Project and make sure you enable cloud messaging for your Google project.

 

STEP 3: Add Config File

Download the GoogleService-Info.plist config and add it to your project.

 

STEP 4: Almost Done!

Enter the Server API Key into the dashboard at https://admin.plotprojects.com/dashboard/.

You are now ready to receive your first notification through QuickSync!

 

Guide for Plot version 1.15.4 and newer:

Add QuickSync to receive your notifications immediately. Starting from 1.15.4 it uses Firebase Messaging. This guide assumes you've integrated Plot using Cocoapods. Make sure you already have integrated Plot using the iOS integration guide.

 

STEP 1: Add To Podfile

Notice: Versions 2.0.5-beta and newer use Firebase version 4.5.0.

Add "pod 'Firebase/Messaging', '3.16.0'" to your Podfile.

pod 'Firebase/Messaging', '3.16.0'

 

STEP 2: Add didReceiveRemoteNotification method

Copy the following snippet into your AppDelegate:

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    [Plot didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}

 

STEP 3: Setup Google Project

Follow the steps at the Google Console to setup your Google Project and make sure you enable cloud messaging for your Google project.

 

STEP 4: Add Config File

Download the GoogleService-Info.plist config and add it to your project. When you use other Firebase functionality in your code, you have to call [FIRApp configure] before calling [Plot initialize...]

 

STEP 5: Almost Done!

Enter the Server API Key into the dashboard at https://admin.plotprojects.com/dashboard/

You are now ready to receive your first notification through QuickSync!

Back To Top

2.16 Upgrading from version 1.x to 2.x

We have updated our plugin to follow the changes made in iOS. Apple deprecated UILocalNotification in favor of UNUserNotificationCenter. Plot Projects no longer makes use of the UILocalNotification.

A change of behaviour in the library is that notifications are now shown to the user when the app is already in the foreground. In version 1.x the notification would be opened straight away without showing it to the user.

Changes to Project settings

Our library now also depends on the UserNotifications.framework, provided by iOS. When using CocoaPods, this dependency is automatically added, so no extra steps are required. Otherwise, you have to add this dependency yourself in the Build Phases screen.

The minimum supported iOS of 2.x is iOS 10. When you want to target iOS 11 features, it is required to make use of this version of our library.

Ensure that all permission description info keys are defined. You can set those in your XCode project settings. You can find them in at the "Custom iOS Target Properties" under the "Info" tab of your build target. The required for iOS 10 and iOS 11 are:

Required Key Description shown in XCode
NSLocationAlwaysUsageDescription Privacy - Location Always Usage Description
NSLocationWhenInUsageUsageDescription Privacy - Location When In Usage Usage Description
NSLocationAlwaysAndWhenInUsageUsageDescription* Privacy - Location Always And When In Usage Usage Description

* this key is added in XCode 9. If you're using XCode 8, you can add the key yourself.

Changes to the AppDelegate

You must still call the initializeWithLaunchOptions: method of the Plot library in the didFinishLaunchingWithOptions method. When your app has its own NotificationCenterDelegate, you must register that one before initializing the Plot Projects plugin.

The method didReceiveLocalNotification: and the corresponding call to [Plot handleNotification:] is no longer required and should be removed.

Changes to Plot classes and the PlotDelegate

You can find the methods for the notification filter, notification handler and geotrigger handler in the PlotDelegate protocol.

The method names in the Plot class and the PlotDelegate stayed the same, but the return types and function parameters have changed from UILocalNotification to UNNotificationRequest. Refer to the reference documentation for the exact method signature. The keys/values in the userInfo fields of notifications and geotriggers remained unchanged.

Back To Top

3. Android Plugin

Android is the mobile operating system developed by Google. This chapter will elaborate on the way our plugin can be used when creating an app for Android.

Back To Top

3.1 How to integrate into an Android project

Notice: When updating from an older version of Plot, make sure no old references to the Plot Projects plugin are in the AndroidManifest. No need to define services of Plot Projects plugin yourself. You do need to register the notification filter and handler yourself when you have one.

To use the library in an Android application, a few steps must be performed.

We have tested compatibility with version 2.2.3 of the Android Gradle plugin.

 

Step 1: Get the library and the dependencies

Previously, you had to download and add the library manually by going into the dashboard and downloading the library under the "Developer Tools" page, even though this is still possible, we automated this process by creating a Maven repository that allows you to include our library with ease. This guide only explains how to use the Maven repository.

Add it to your project dependencies. Replace the version parameter with the version of your plugin.

For versions 2.2.1-beta and up, the library has a dependency on Google Play Services (version 11.2.0) for Nearby, Location and GCM. However, you have to include the Google maven repository for this dependency to work.

repositories {
   jcenter()
   maven {
     url 'https://maven-repo.plotprojects.com'
   }
   maven {//using google() when using a recent version is also possible
        url "https://maven.google.com"
    }
}
dependencies {
    //specify an explicit version number to ensure you don't get unexpected updates
    compile 'com.plotprojects:plot-android:2.4.0-beta'
}

For earlier versions, you need to add these dependencies, as follows:

repositories {
   jcenter()
   maven {
     url 'https://maven-repo.plotprojects.com'
   }
}
dependencies {
   compile group:'com.plotprojects', name: 'plot-android', version:'2.1.0-beta', ext:'aar'

   compile 'com.google.android.gms:play-services-gcm:11.0.4'
   compile 'com.google.android.gms:play-services-location:11.0.4'
   compile 'com.google.android.gms:play-services-nearby:11.0.4'
}

Notice: Note that the dependencies com.google.android.gms:play-services-gcm and com.firebase:firebase-jobdispatcher are incompatible with each other. If your app requires firebase-jobdispatcher, you have to use com.firebase:firebase-jobdispatcher-with-gcm-dep instead. It should be a drop-in replacement.

 

Step 2: Set minSdkVersion

Set the minSdkVersion version to at least 14. When using Gradle you can do that by changing build.gradle in the folder of your app.

defaultConfig {
    applicationId "com.myplotapplication"
    minSdkVersion 14
    targetSdkVersion 22
    versionCode 1
    versionName "1.0"
}

 

Step 3: Define configuration file

Plot uses a configuration file which you have to define as plotconfig.json in your assets folder. When no assets folder is available, you can create one in Android Studio by right clicking on your project, in the Project tool window, and then selecting New / Folder / Assets.

An example of such a config file can be found on our dashboard, as well as the public token you will have to use.

{
    "publicToken": "REPLACE_ME",
    "enableOnFirstRun": true,
    "debug": true
}

 

Step 4: Almost done!

Call Plot.init(context) to initialize the library from your main Activity.

When calling init from an activity, you can use the this keyword as the first parameter.

import com.plotprojects.retail.android.Plot;

public class MyActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        Plot.init(this);
    }
}

An example configuration file and your public token can be found on the Download page on our dashboard. You are now ready to receive your first notification. Need more help during testing, look at the test guide.

For more details, look at the testing section of the documentation.

Back To Top

3.2 Android Test Guide

This guide shows how to verify the Android integration of the Plot plugin

  1. Receiving Of Notifications Test
  2. Debug mode and log messages
  3. Sending the Debug Log via e-mail
  4. Location testing using emulator
  5. Location Testing using testLocation() method
  6. Wrap up

 

1. Receiving Of Notifications Test

After completing the basic integration of the Plot Projects SDK, you need to test it. You can verify if the Plot plugin is integrated properly by receiving a location based notification. Once you receive a notification, you know the basic integration is successful.

How to test the basic integration of the Plot Projects Android SDK in your app:

  1. In your application's code, ensure the "debug" property is set to true, as it allows the plugin to show what is happening. The following code snippet shows an example of how to do that. All you need to add the second line to your plotconfig.json file:
    {
      "publicToken": "YOUR_TOKEN",
      "debug": true,
      "automaticallyAskLocationPermission": true,
      "enableOnFirstRun": true
    }
  2. Ensure your test app is connected to your sandbox environment in Plot Projects to prevent your end-users from receiving test notifications. If you don't have a Sandbox environment yet, you can create one by clicking on your app in the Plot Dashboard > Manage apps and plans > Create new app.
  3. Install your app on your phone. If it is already installed, then remove the app and reinstall it, so you can start from a clean slate.
  4. Log in to the Plot Projects dashboard
  5. When in your Sandbox app, go to the Notification Campaigns screen by clicking on the corresponding menu item. At the bottom right, you can create a new Notification Campaign.
  6. Give the campaign a name and a message. You can ignore the fields on the Advanced Settings screen.
  7. Select the action "Open app". If you don't have a geofence yet at your location, you can create one now on this screen. Place the geofence at the location where you're currently are. The geofence radius should be kept at 200 meters.
  8. Select in the "Users should receive notifications" section the option "More than once" and save your campaign.
  9. Note that you will NOT receive this notification on your device immediately. The Plot Projects SDK only connects to our backend periodically (every 2 hours or when the device has moved significantly) to update its cached campaigns. This isn't influenced by whether the app has been opened or closed in this period. Therefore, when a new notification has been added it may take a while before that notification is downloaded and may be received by you. If you don't want to wait this long you have a couple of options:
    1. You can trigger a backend call by clearing the local database of your app on your phone. To clear the local database you have to open the Apps section under settings on your phone/emulator and find your app. There you can stop the app and clear local data under storage section. When the app is then opened again it will directly start downloading the notifications and, when you are at the right location of course, show the notifications. The following screenshots illustrate how to achieve that:
    2. You can set up the Plot Projects feature Quicksync, allowing you to instantly send new campaigns to all your app users (see our Quicksync integration guide).
  10. If you didn't receive your test notification after a couple minutes you can use this checklist.

Notice: When a notification has been received, it won't be sent again until you leave the geofence. Cleaning the local database will make it possible to receive a notification again. This can make testing easier.

 

2. Debug mode and log messages

Notice: You need to turn off debug before submitting to app store by setting "debug": false in your plotconfig.json

The Plot plugin provides log messages to help you diagnose situations where no notification is shown. For example, it helps you distinguish between situations where either our library thinks it isn't close enough to a location or the notification filter dropped the notification.

Since version 2.x, in order for Plot plugin to log these messages, you have to enable debug mode. That is done by setting debug to true in plotconfig.json. Notice the last line of the following code snippet:

{
  "publicToken": "YOUR_TOKEN",
  "enableOnFirstRun": true,
  "debug": true
}

The messages are then sent to LogCat. Most IDEs show these messages directly from there.

When enabling Plot you see the following log message:

10-04 10:53:27.362 5834-6480/com.example D/Plot/SettingsService: Enabling Plot plugin.

After the Plot plugin is enabled, it downloads the notifications from the server. It shows the total number of notifications and the notifications that have been loaded. You can use the following message to ensure the right notifications are loaded.

10-04 10:53:34.673 5834-6480/com.example D/Plot/BasicNotificationService: Received 39 notifications.

10-04 10:53:36.411 5834-6480/com.example D/Plot/BasicNotificationService: Loaded Notification{id='9f82ae0ad3b94a498bdbfb9f163d75a4',
    location=Location{latitude=52.373150255778086, longitude=4.905467582617121}, message='...', timespans=[], data='...', matchRange='4520', triggerOnExit='false',
    dwellingMinutes='0', cooldownGroups=[Cooldown{cooldownSeconds=1, groupName='9f82ae0ad3b94a498bdbfb9f163d75a4'}], landingPageNotification='false', geotrigger='false',
    isAppLinkNotification='false', segmentationIds='[]', segmentationProperties='[]'}

Once the notifications are loaded, Plot matches these. It shows the loaded notifications that and the distance to these notifications in meters. Where the distance is smaller than the match range, a notification "matches" and is sent to the notification filter (if you have one defined).

10-04 10:53:36.590 5834-6480/com.example D/Plot/GeofenceMatching: Checking for geofence matches.

10-04 10:53:36.693 5834-6480/com.example D/Plot/GeofenceMatching: Distance to 37939d977fa744339bcfbb1de5833b37;cbf373cfa41248ee837799099f5c99c0: 43 (match range: 200)

When there is at least one notification sent to the notification filter, then you see the following two lines. First the number of matching notifications, followed by details about these notifications. When you don't have a notification filter, then this step is skipped.

10-04 10:53:37.569 5834-6643/com.example D/Plot/NotificationFilterUtil: Received 1 notifications for filtering

10-04 10:53:37.578 5834-6643/com.example D/Plot/NotificationFilterUtil: FilterableNotification(id = 471b01eb41af436f9cb38196936a727c;41b1ce9a9f2140ce9512f03b4fafc04b, matchId = 82086267-d4b1-4eea-972c-95a841ffb3a2, message = 15/9 13:55 test quicksync, data = , notification = null, trigger = enter)

Once the notification filter completes, the following log message appears. It shows how many notifications passed through the notification filter and then shows them. These notifications then appear in the notification area.

10-04 10:53:37.669 5834-6643/com.example D/Plot/NotificationFilterUtil: 1 notifications passed

10-04 10:53:37.674 5834-6643/com.example D/Plot/NotificationFilterUtil: FilterableNotification(id = 471b01eb41af436f9cb38196936a727c;41b1ce9a9f2140ce9512f03b4fafc04b, matchId = 82086267-d4b1-4eea-972c-95a841ffb3a2, message = Wednesday: 15/9 13:55 test quicksync, data = , notification = null, trigger = enter)

 

3. Sending the Debug Log via mail

To read the log, you can mail the debug log to yourself. With Plot all you have to do is call Plot.mailDebugLog() in your app, e.g. after a button click event. The method will start your mail client so you can send the debug log to yourself or your another developer. An example of this can be seen in our demo apps, which you can download from our dashboard.

 

4. Location testing using emulator

Since version 2.4, Plot plugin supports two ways of location testing on an emulator. The first method is to enable the emulator testing mode and the second option is to use the Plot.testLocation() method to set an explicit location.

When enabling the emulator testing mode the plugin checks the location more frequent than it normally would and it starts using the GPS location provider. The reason for this is that the emulator forwards the virtual location as a GPS location. When setting emulatorTesting to true in the plotconfig.json, the plugin increases the battery usage significantly. Make sure you disable it before submitting to App Store.

In order to use an emulator, you need to set the following properties in plotconfig.json file:

"debug": true,
"emulatorTesting": true

Emulator testing is only enabled when debug is set to true. Otherwise, it is ignored.

After setting the previous properties, you use Android emulator location settings to change your location. To access the location screen, first you click on the three dots as shown in the following picture:

Then set the testing location as shown below. The part within the red rectangle is where you set the test location.

 

5. Location Testing using testLocation() method

Another option is to change the location for testing purpose programmatically. For this, the plugin has the following method:

Plot.testLocation() takes either a combination of latitude and longitude, or a Location object.

Changing location using the testLocation method is only available in debug mode. You need to set

"debug": true

in plotconfig.json before you can use that method. You also need to call it, after Plot plugin is initialized.

 

6. Wrap up

Testing your Android integration isn't hard. We have shown you how you can verify that your app successfully receives notifications and how to understand the log messages Plot may print. Don't forget to disable the debug log messages when releasing your application.

We hope that this blogpost clarifies how to properly integrate the Plot plugin into your Android application. If you have problems during one of these steps, you can post your on Stackoverflow. Or contact your customer success manager with questions. We'll help you.

Back To Top

3.3 Functionality

The plugin targets Android 2.3 (Froyo, API level 9) and up. When the Plot plugin is initialized by the Plot.init() call, it checks if it was previously enabled. If the location monitoring service is not running and it was previously enabled it will (re)enable the location monitoring service. The location monitoring service will then also be restarted automatically after the device reboots.

The plugin will start a background service which will periodically poll the location of the user. The location of the user will be determined in a way that minimizes battery usage; instead of GPS the service uses Wifi-triangulation. When the user is within the radius of a geofence (default: 200 meters or 220 yards) with a published notification it will present a notification to the user. This notification can optionally be modified or filtered.

We provide a default implementation to open a browser with the URL enclosed in the notification. It is possible to replace this implementation with your own. An example of such an implementation is given later. The location polling frequency is determined automatically and is at least once every 10 minutes, but can be more frequent depending on a number of factors. The Plot plugin is optimized for users traveling at low speeds (walking, cycling). The geofences and notifications will be synchronized with our backend every couple hours. When traveling at higher speeds or when a phone can temporarily not determine its location, it is possible that a Location Based Notification is not sent even when a user is near a geofence.

iBeacon notifications are supported for our Android plugin (from version 1.7.0 and up) as well, unless you're using Appcelerator.

iBeacons allow you to target users within smaller ranges, for instance inside a store or other kind of buildings. You can add iBeacons just like normal geofences in our dashboard. Instead of a latitude and longitude, iBeacons are identified by a proximity UUID, a majorId and a minorId. iBeacon notifications are also passed through the Notification Filter and the Notification Handler as normal notifications from the Plot plugin would. Please note that iBeacons require an Android verion of at least 4.3 and Bluetooth low-energy. Read all documentation regarding our iBeacon support in Chapter 2: iBeacons.

It is possible to enable debug logging on Plot. Use this to receive more feedback when developing with Plot.

Back To Top

3.4 Notification handling

When you want the default behavior when opening a notification, which is opening a URI, you have to follow the description in step three of the previous section. If you want a different action, then you have to write your own BroadcastReceiver.

An example of a custom receiver which starts the NotificationOpenActivity (see our example project):

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.plotprojects.retail.android.FilterableNotification;

public class MyNotificationOpenReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        FilterableNotification notification = intent.getParcelableExtra("notification");
        if (notification.getData() == null)
            return;

        Intent openIntent = new Intent(context, NotificationOpenActivity.class);
        openIntent.setAction(NotificationOpenActivity.ACTION);
        openIntent.putExtras(intent.getExtras());
        openIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);

        context.startActivity(openIntent);
    }
}

And to add this receiver to the manifest instead of the default one:

<receiver android:exported="false" android:name="com.example.MyNotificationOpenReceiver">
  <intent-filter>
    <action android:name="${applicationId}.plot.OpenNotification" />
  </intent-filter>
</receiver>

Back To Top

3.5 Notification filtering

When you want to segment your users or want to personalize the notifications, you can use the notification filter. Plot automatically detects whether a service is registered in AndroidManifest.xml that extends from the class NotificationFilterBroadcastReceiver. Implementations of NotificationFilterReceiver must implement the method public List<FilterableNotification> filterNotifications(List<FilterableNotification> notifications). When the service is defined Plot will send the notifications to this method before showing them on the mobile device. This allows you to prevent notifications from being shown or change the notifications.

The “data” field of a notification allows you to add custom information to a notification in our dashboard that you can access in the filterNotifications() method. Plot doesn’t prescribe a format for this data. You can use plain text, or for example use JSON.

//Example implementation for filterNotifications:
public class MyNotificationFilterReceiver extends NotificationFilterBroadcastReceiver {
    @Override
    public List<FilterableNotification> filterNotifications(List<FilterableNotification> notifications) {
        String format = "Hello Paul: %s";
        for (FilterableNotification notification : notifications) {
            String newMessage = String.format(format, notification.getMessage());
            notification.setMessage(newMessage);
        }
        return notifications;
    }
}

And add this receiver to the manifest:

<receiver android:name=".MyNotificationFilterReceiver" android:exported="false">
            <intent-filter>
                <action android:name="${applicationId}.plot.FilterNotifications" />
            </intent-filter>
</receiver>

It is possible to change the message with the setMessage() method or it is even possible to provide a custom Notification with the setNotification() method on FilterableNotification. By providing a custom notification object it is possible to send rich notifications, for example notifications with an image, to your users. When no custom Notification is specified, Plot will generate a Notification based on the message field and show that one.

We have written a more extensive blog post about this: Using The Notification Filter To Increase Relevance. A larger example is given in another blog post: Using Plot To Create Context-Aware Coupons, Offers And Promotions.

Back To Top

3.6 Geotrigger handler

When you want to handle your geotriggers, or use them as trigger events for your own code, you can use the geotrigger handler. Plot automatically detects whether a service is registered in AndroidManifest.xml that extends from the class GeotriggerHandlerBroadcastReceiver. Implementations of GeotriggerHandlerReceiver must implement the method public List<Geotrigger> handleGeotriggers(List<Geotrigger> geotriggers). When the service is defined, Plot will send the geotriggers to this method before considering them as handled. This allows you to add custom code that is triggered by entering (or exiting) a geofence or beacon region.

//Example implementation for handleGeotriggers:
public class MyGeotriggerHandlerReceiver extends GeotriggerHandlerBroadcastReceiver {
    @Override
    public List<Geotrigger> handleGeotriggers(List<Geotrigger> geotriggers) {
        List<Geotrigger> passedGeotriggers = new ArrayList<Geotrigger>();
        for (Geotrigger geotrigger : geotriggers) {
            String data = geotrigger.getData();
            if (data.equals("pass")) {
                passedGeotriggers.add(geotrigger);
            }
        }
        return passedGeotriggers;
    }
}

And add this receiver to the manifest:

<receiver android:name=".MyGeotriggerHandlerReceiver" android:exported="false">
            <intent-filter>
                <action android:name="${applicationId}.plot.HandleGeotriggers" />
            </intent-filter>
</receiver>

You can read all fields from a geotrigger just as you would do that for a notification in the notification filter. Full reference for this can be found in the library reference.

Back To Top

3.7 Retrieve cached notifications

It is possible to retrieve the list of notifications and geotriggers the Plot library is currently listening to. You can, for example, use this to show the user what is near him. This can also be used to see what Plot has loaded for debugging purposes.

The plugin exposes two method: Plot.getLoadedNotifications() and Plot.getLoadedGeotriggers(). Fields like notification message, latitude, longitude, data are available.

When no notifications are loaded an empty list is returned. This could for example be the case when the location of the device is unknown.

Back To Top

3.8 List sent notifications and geotriggers

The library allows you to retrieve the sent notifications and geotriggers using the method Plot.getSentNotifications() for notifications and Plot.getSentGeotriggers() for geotriggers. The library will retain up to 100 notifications and geotriggers, before the oldest notifications/geotriggers get deleted. When you alter the notification message or the data property, this alteration will also be applied to the notification in the history. The objects returned contain the time the notification or geotrigger was sent and when, if it has, been opened or handled.

Because this method uses blocking I/O, this method cannot be run on the main thread. Instead it should be run on a worker thread or in an AsyncTask.

It is possible to remove the history of sent notifications and geotriggers yourself by using the Plot.clearSentNotifications() method for notifications and the Plot.clearSentGeotriggers() method for geotriggers.

An use case where this functionality may be useful for is to show a list of the notifications that were sent since the app was last opened. This allows users to see the notifications again, even though they may have dismissed them earlier.

Back To Top

3.9 Notification events

Since plugin version 1.15.0 it is possible to listen to notification events. This feature is especially useful when you want to tie the plugin to your own analytics.

Currently we offer notification events upon showing a notification to the user (sent notification event) and whenever a user taps on a notification (opened notification event).

Whenever such an event happens our plugin will send out an intent to which you can listen with a broadcast receiver. When implementing make sure to include it in the manifest, for example like this:

  <receiver android:exported="false" android:name="${applicationId}.MyNotificationEventReceiver">
      <intent-filter>
          <action android:name="${applicationId}.plot.SentNotification" />
          <action android:name="${applicationId}.plot.OpenedNotification" />
      </intent-filter>
  </receiver>

See an example implementation below for the notification sent and opened event:

public class MyNotificationEventReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        SentNotification notification = intent.getParcelableExtra("notification");
        if ((packageName + ".plot.SentNotification").equals(intent.getAction())) {
          String format = "Message of the sent notification: %s";
          Log.i(TAG, String.format(format, notification.getMessage()));
        } else if ((packageName + ".plot.OpenedNotification").equals(intent.getAction())) {
          String format = "Message of the opened notification: %s";
          Log.i(TAG, String.format(format, notification.getMessage()));
          // Make a call to your Google Analytics
        }
    }
}

Back To Top

3.10 Example implementation

This is a minimal example which shows how to integrate Plot. It doesn't have a Notification Filter and uses the default notification handler.

Example content for your assets/plotconfig.json file: (you can get one specifically for your app in our dashboard)

{
  "publicToken": "REPLACE_ME",
  "enableOnFirstRun": true,
  "debug": true
}

Example code for in your activity:

public class PlotExample extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Plot.init(this);
    }
}

Back To Top

3.12 iBeacons

Starting from version 2.0 of our library, it is no longer required to follow extra steps to have beacon support. Beacon support is enabled by default.

Please note that in order to receive iBeacon notifications, Android devices have to run on Android 4.3 or higher and have Bluetooth low-energy support. For further information about iBeacons in general, see Chapter 2: iBeacons.

Back To Top

3.13 Segmentation

The segmentation feature is introduced in version 1.10.0 of our plugin and further improved by segmentation on campaign history in version 1.12.0. Segmentation allows you to limit specific notifications to specific groups of users. This prevents your end users from receiving notifications that aren't relevant for them.

Two steps are needed when using segmentation, first the segment property and the appropriate value have to be set in the campaign (or notification) in the dashboard. Next to that they have to be set inside your app. When these match, the device will receive the notification.

For each type we expose methods to conveniently set a segment. An example for each type is shown below. When setting a value for an existing property the previous value gets overwritten.

// Set the segment for being a premium member to true.
Plot.setBooleanSegmentationProperty("premiumMember", true);

// Set the segment for gender to male.
Plot.setStringSegmentationProperty("gender", "M");

// Set the segment for year of birth to 1980.
Plot.setLongSegmentationProperty("yearOfBirth", 1980);

// Set the segment for money spent to $10.35.
Plot.setDoubleSegmentationProperty("moneySpent", 10.35);

// Set the signup date segment (the value is in seconds since the UNIX Epoch, just as System.currentTimeMillis()/1000).
Plot.setDateSegmentationProperty("signUp", 1426503567);

Note: the segmentation key has a limit of 40 characters and the value of 40 characters

More general information about segmentation is available in the segmentation guide.

Back To Top

2.16 Android QuickSync Integration Guide

Add QuickSync to receive your notifications immediately. This uses Firebase Messaging and it dependents on Google Play Services. Make sure you already have integrated Plot using the Android integration guide.

 

Step 1: Add Firebase Messaging Dependency

Add a dependency on Firebase in your app-level gradle file. The download page shows with what version it has been tested. It is possible it won't work with newer major versions of Google Play Services.

dependencies {
  //ensure the version of the Firebase libraries are the same as of your Google Play Services dependency
  compile 'com.google.firebase:firebase-core:' + googlePlayVersion
  compile 'com.google.firebase:firebase-messaging:' + googlePlayVersion
}

 

Step 2: Add Services

Add a service registration to your manifest as shown in the snippet if you don't have Firebase Messaging integrated yet.

<service
		android:name="com.plotprojects.retail.android.QuickSyncFirebaseMessagingService">
		<intent-filter>
				<action android:name="com.google.firebase.MESSAGING_EVENT" />
		</intent-filter>
</service>

<service
		android:name="com.plotprojects.retail.android.QuickSyncFirebaseInstanceIdService">
		<intent-filter>
				<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
		</intent-filter>
</service>

When you have your own Firebase Messaging services inside your app, you can forward calls from these services to our library. The QuickSyncFirebaseInstanceIdService has the static method handleTokenRefresh(Context) for tokenRefresh events and the QuickSyncFirebaseMessagingService has the static method handleMessageReceived(Context, RemoteMessage) for messageReceived events.

 

Step 3: Setup a Firebase Project

Follow the steps at the Firebase Console to setup your project and make sure you enable cloud messaging for your project.

 

Step 4: Add Config File

To obtain the google-services.json config file, add your Android app to Firebase by clicking on the "Add Firebase to your Android app" and following the instructions.

In case your Firebase project already has the Android app, go to the General tab in the Project Settings page and retrieve the config file, as shown in the image below.

Once the google-services.json config is downloaded, add it into your project's module folder, typically app/.

 

Step 5: Almost done!

After performing the steps above, in order to get the server key, click the settings button, highlighted in red, followed by Project Settings.

Then look up the Legacy server key found in the Cloud Messaging tab of the Settings page, as presented below.

Add that code to the dashboard in the Developer Tools page.

You are now ready to receive your first notification through QuickSync!

Back To Top

4. Appcelerator Plugin

The Appcelerator module is available from the Marketplace: Plot: Location Based Notifications Module and the source code is available on GitHub. In addition, our module can be downloaded and installed in your project using gitTio: $ gittio install com.plotprojects.ti (also available here).

We have blogged about how to integrate Plot into your Appcelerator project here and have an integration guide here.

Back To Top

4.1 How to integrate into an Appcelerator project

To install the Plot plugin into your Appcelerator Titanium app only a couple of small steps have to be performed. Note that this module was developed for Titanium 6.2.2.GA or newer. This plugin supports both iOS and Android.

 

Step 1: Download The Zip

Log into our dashboard, go to the "Developer Tools" tab, by clicking on "Download Plot Projects SDK". There you find the latest version of Appcelerator module. The plugin can be obtained as a .zip file found under "Appcelerator Titanium Module" on that page. Don't have a Plot Projects account? Sign up for free!

 

Step 2: Install in Appcelerator Studio

After you downloaded the .zip for the plugin, you install it in Appcelerator Studio by following the following steps:

  1. Open Appcelerator Studio.
  2. In the Help menu, select Install Mobile Module.
  3. Insert the .zip file obtained in the previous step.

 

Step 3: Add Configuration File

Before using the plugin, you add a configuration file in the assets folder and name the file plotconfig.json. The snippet on the right shows an example of the file. You look up your public token in the dashboard.

{
    "publicToken": "REPLACE_ME",
    "enableOnFirstRun": true
}

 

Step 4: Set permission rationale

Note that if your app also targets iOS, then it is required to specify why your app requires location services. You do that in your plist. Add the following lines to tiApp.xml at the ios/plist/dict element:

<key>NSLocationAlwaysUsageDescription</key>
<string>The app uses your location in order to inform you about special offers in nearby stores.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>The app uses your location in order to filter information shown based on what's near you.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>The app uses your location in order to inform you about special offers in nearby stores and customize its content based on what's near.</string>

 

Step 5: Almost done!

Add the snippet below to one of your scripts used to initialize your application. You usually do this in app.js or alloy.js:

var plot = require('com.plotprojects.ti');
plot.initPlot({ notificationFilterEnabled: false });

You are now ready to receive your first notification. For more details, look at our Github page.

Need more help during testing, look at the testing section of the documentation.

Back To Top

4.2 Notification handling

When you don't specify a callback for handling notifications, Plot will handle the notifications depending on the action setting in the dashboard. You can for instance set the field to a URI and whenver the notification is opened the URI will be loaded with the phone's browser.

If you don’t want Plot to handle the notifications, you can handle the notifications yourself. To change the action when a notification has been received you can add a listener as shown in the snippet below. The function is passed a notification object, which has the fields "message", "data" and "identifier". When no listener is added, then the "data" field will be treated as set in the dashboard.

plot.addEventListener("plotNotificationReceived", func)

Back To Top

4.3 Notification filtering

When you want to segment your users or want to personalize the notifications, you can use the notification filter. The notification filter allows you to filter out or edit notifications before they are shown. To enable the notification filter, you add the property notificationFilterEnabled with the value true to object passed to initPlot. When the notification filter is disabled the notification filter script won't be executed and all notifications will shown.

You define the filter in assets/plotfilter.js. When Plot detects that a notification could be shown, it executes the script. The script runs in a different context than the normal scripts are executed. Therefore you cannot reference views or global variables from the notification filter.

The message and the data property of the notification can be modified. You can remove notifications from the array you don't want to show. Always call plot.popFilterableNotifications() and plot.sendNotifications(filterableNotifications), even when no notifications will be shown.

An example for assets/plotfilter.js:

var plot = require('com.plotprojects.ti');

Ti.API.info('Notification Filter. Plot version: ' + plot.version);

var filterableNotifications = plot.popFilterableNotifications();

for (var i = 0; i < filterableNotifications.notifications.length; i++) {
var n = filterableNotifications.notifications[i];
n.message = "TestMessage: " + n.message;
n.data = "Test123: " + n.data;
}

//always call plot.sendNotifications function, even if filterableNotifications.notifications becomes empty
plot.sendNotifications(filterableNotifications);

Back To Top

4.4 Geotrigger handling

When you want to handle your geotriggers, or use them as trigger events for your own code, you can use the geotrigger handler. To enable the geotrigger handler, you add the property geotriggerHandlerEnabled with the value true to object passed to initPlot. When the geotrigger handler is disabled all geotriggers will be counted as handled.

You define the handler in assets/plotgeotriggerhandler.js. When Plot detects that a geotrigger has triggered, it executes the script. The script runs in a different context than the normal scripts are executed. Therefore you cannot reference views or global variables from the geotrigger handler.

You can remove geotriggers from the array you don't want to mark as handled. Always call plot.popGeotriggers() and plot.markGeotriggersHandled(geotriggers).

An example for assets/plotgeotriggerhandler.js:

var plot = require('com.plotprojects.ti');

Ti.API.info('Plot version: ' + plot.version);

var geotriggersHandler = plot.popGeotriggers();
var geotriggersPassed = [];

for (var i = 0; i < geotriggersHandler.geotriggers.length; i++) {
	var geotrigger = geotriggersHandler.geotriggers[i];
	if (geotrigger.data == "pass") {
		geotriggersPassed.push(geotrigger);
	}

	Ti.API.info(JSON.stringify(geotrigger));
}

geotriggersHandler.geotriggers = geotriggersPassed;

//always call plot.markGeoTriggersHandled function, even if geotriggersPassed becomes empty
plot.markGeoTriggersHandled(geotriggersHandler);

Back To Top

4.5 Retrieve cached notifications

It is possible to retrieve the list of notifications and geotriggers the Plot library is currently listening to. You can, for example, use this to show the user what is near him. This can also be used to see what Plot has loaded for debugging purposes.

The plugin exposes two method: getLoadedNotifications() and getLoadedGeotriggers(). Fields like notification message, latitude, longitude, data are available.

When no notifications are loaded an empty list is returned. This could for example be the case when the location of the device is unknown.

Please note that this is an optional feature and not needed in order for the Plot library to work.

An example implementation would be:

var plot = require('com.plotprojects.ti');

var cachedNotifications = plot.getLoadedNotifications();
var cachedGeotriggers = plot.getLoadedGeotriggers();

Back To Top

4.6 List sent notifications and geotriggers

The library allows you to retrieve the sent notifications and geotriggers using the method plot.getSentNotifications() for notifications and plot.getSentGeotriggers() for geotriggers. The library will retain up to 100 notifications and geotriggers, before the oldest notifications/geotriggers get deleted. When you alter the notification message or the data property, this alteration will also be applied to the notification in the history. The objects returned contain the time the notification or geotrigger was sent and when, if it has, been opened or handled.

It is possible to remove the history of sent notifications and geotriggers yourself by using the plot.clearSentNotifications() method for notifications and the plot.clearSentGeotriggers() method for geotriggers.

An use case where this functionality may be useful for is to show a list of the notifications that were sent since the app was last opened. This allows users to see the notifications again, even though they may have dismissed them earlier.

Back To Top

4.7 iBeacons

Our Appcelerator Plugin supports iBeacons only for iOS.

Back To Top

4.8 Segmentation

The segmentation feature is introduced in version 1.10.0 of our plugin and further improved by segmentation on campaign history in version 1.12.0. Segmentation allows you to limit specific notifications to specific groups of users. This prevents your end users from receiving notifications that aren't relevant for them.

Two steps are needed when using segmentation, first the segment property and the appropriate value have to be set in the campaign (or notification) in the dashboard. Next to that they have to be set inside your app. When these match, the device will receive the notification.

For each type we expose methods to conveniently set a segment. An example for each type is shown below. When setting a value for an existing property the previous value gets overwritten.

// Set the segment for being a premium member to true.
plot.setBooleanSegmentationProperty("premiumMember", true);

// Set the segment for gender to male.
plot.setStringSegmentationProperty("gender", "M");

// Set the segment for year of birth to 1980.
plot.setIntegerSegmentationProperty("yearOfBirth", 1980);

// Set the segment for money spent to $10.35.
plot.setDoubleSegmentationProperty("moneySpent", 10.35);

// Set the sign-up date segment to now.
plot.setDateSegmentationProperty("signUp", new Date());

Note: the segmentation key has a limit of 40 characters and the value of 40 characters

More general information about segmentation is available in the segmentation guide.

Back To Top

5.1 How to integrate into an Phonegap project

To install the Plot plugin into your PhoneGap/Cordova/Ionic app only a couple of small steps have to be performed. Note that this plugin requires PhoneGap 3.0.0 or higher. This plugin supports both iOS 6 or newer, and Android 2.3 or newer.

 

Step 1: Get The Plugin

There are two ways to get the plugin:

i) Use config.xml

Add the following line to config.xml to add our plugin.

<gap:plugin name="cordova-plotprojects" source="npm" version="1.x" />
ii) Command line

You can add the plugin to an existing project by executing the following command:

PhoneGap:

phonegap plugin add cordova-plotprojects

Cordova/Ionic:

cordova plugin add cordova-plotprojects

 

Step 2: Add Configuration File

Before you can use the plugin, you have to add a configuration file in the www/folder and name the file plotconfig.json. The snippet on the right shows an example of the file. You can find your public token in the dashboard.

{
    "publicToken": "REPLACE_ME",
    "enableOnFirstRun": true
}

 

Step 3: Almost done!

You can initialize the Plot library using the snippet on the right.

<script type="text/javascript">// <![CDATA[ document.addEventListener("deviceready", deviceReady, true); function deviceReady() { var plot = cordova.require("cordova/plugin/plot"); plot.init(); } // ]]></script>

You are now ready to receive your first notification. For more details, look at our Github page.

Need more help during testing, look at the testing section of the documentation.

Back To Top

5.2 Notification handling

When you don't specify a callback for handling notifications, Plot will handle the notifications depending on the action setting in the dashboard. You can for instance set the field to a URI and whenever the notification is opened the URI will be loaded with the phone's browser.

If you don’t want Plot to handle the notifications, you can handle the notifications yourself. To change the action when a notification has been received you can use the notificationHandler. This feature is available both on IOS and Android.

An example of such an implementation:

//Optional, by default the data is treated as set in the dashboard.
plot.notificationHandler = function(notification, data) {
alert(data);
}

Back To Top

5.3 Notification filtering

When you want to segment your users or want to personalize the notifications, you can use the notification filter. The notification filter allows you to filter out or edit notifications before they are shown.

To do this, you can intercept notifications before they are shown by using the filterCallback. Keep in mind this feature is only available on IOS.

An example of such an implementation:

//Optional, by default all notifications are sent.
plot.filterCallback = function(notifications) {
  for (var i = 0; i < notifications.length; i++) {
    notifications[i].message = "NewMessage";
    notifications[i].data = "http://www.example.com";
  }
    return notifications;
};

Back To Top

5.4 Retrieving cached notifications

It is possible to retrieve the list of notifications and geotriggers the Plot library is currently listening to. You can, for example, use this to show the user what is near him. This can also be used to see what Plot has loaded for debugging purposes.

The plugin exposes two method: loadedNotifications(callback) and loadedGeotriggers(callback). Fields like notification message, latitude, longitude, data are available.

When no notifications are loaded an empty list is returned. This could for example be the case when the location of the device is unknown.

Please note that this is an optional feature and not needed in order for the Plot library to work.

An example implementation would be:

plot.loadedNotifications(function(notifications) {
  // Do something with the notifications
});
plot.loadedGeotriggers(function(geotriggers) {
  // Do something with the geotriggers
});

Back To Top

5.5 List sent notifications and geotriggers

The library allows you to retrieve the sent notifications and geotriggers using the method plot.sentNotifications(resultCallback, errorCallback) for notifications and plot.sentGeotriggers(resultCallback, errorCallback) for geotriggers. The library will retain up to 100 notifications and geotriggers, before the oldest notifications/geotriggers get deleted. When you alter the notification message or the data property, this alteration will also be applied to the notification in the history. The objects returned contain the time the notification or geotrigger was sent and when, if it has, been opened or handled.

It is possible to remove those notifications yourself as well using the plot.clearSentNotifications() method for notifications and the plot.clearSentGeotriggers() method for geotriggers.

An use case where this functionality may be useful for is to show a list of the notifications that were sent since the app was last opened. This allows users to see the notifications again, even though they may have dismissed them earlier.

Back To Top

5.6 iBeacons

Our Phonegap Plugin supports iBeacons for both Android and iOS, however, you need to perform some additional steps for Android. To keep our normal Android library small and to prevent always having to add Bluetooth permissions we ship Android iBeacon support in a separate plugin.

You can find this module at: https://github.com/Plotprojects/plot-phonegap-plugin-androidibeacons The module adds functionality to the existing module, so you still have to add the core Plot Plugin in your project.

Please note that in order to receive iBeacon notifications, Android devices have to run on Android 4.3 or higher and have Bluetooth low-energy support. For further information about iBeacons in general, see Chapter 2: iBeacons.

Back To Top

5.7 Segmentation

The segmentation feature is introduced in version 1.10.0 of our plugin and further improved by segmentation on campaign history in version 1.12.0. Segmentation allows you to limit specific notifications to specific groups of users. This prevents your end users from receiving notifications that aren't relevant for them.

Two steps are needed when using segmentation, first the segment property and the appropriate value have to be set in the campaign (or notification) in the dashboard. Next to that they have to be set inside your app. When these match, the device will receive the notification.

For each type we expose methods to conveniently set a segment. An example for each type is shown below. When setting a value for an existing property the previous value gets overwritten.

// Set the segment for being a premium member to true.
plot.setBooleanSegmentationProperty("premiumMember", true);

// Set the segment for gender to male.
plot.setStringSegmentationProperty("gender", "M");

// Set the segment for year of birth to 1980.
plot.setIntegerSegmentationProperty("yearOfBirth", 1980);

// Set the segment for money spent to $10.35.
plot.setDoubleSegmentationProperty("moneySpent", 10.35);

// Set the sign-up date segment to now.
plot.setDateSegmentationProperty("signUp", new Date());

Note: the segmentation key has a limit of 40 characters and the value of 40 characters

More general information about segmentation is available in the segmentation guide.

Back To Top

6. Xamarin Plugin

The Plot Projects Xamarin plugin is available for both iOS and Android. The plugin isn't available for the Xamarin Starter Edition, since it uses native bindings. We recommend installing the plugin via NuGet. We also have it available on github: https://github.com/Plotprojects/plot-xamarin-plugin

You can find all the steps needed for a simple integration at the integration guide.

Back To Top

6.1 How to integrate into a Xamarin project

We assume in this guide you already have an account for our dashboard. Don't have an account yet? Sign up for free!

 

Step 1: Both iOS & Android

Our library supports both iOS and Android. We recommend installing our plugin through NuGet as it automatically ensures the right version of our library is included. You can find the plugin in the NuGet gallery under the name "PlotProjects.Plugin".

It is possible to make use of the IPlot interface in your own portable library projects, but then you still have to add the Plot Projects Xamarin Plugin to the platform specific projects as well.

 

Step 2: Android Step Only

You can skip this section when your app doesn't need Android support.

Place plotconfig.json in the Assets folder of your Android project. You can configure Plot through the configuration file. You can find an example config file and your public token on the Developer page on our dashboard.

 

Step 3: Android Step Only

You can skip this section when your app doesn't need Android support.

Call PlotProjects.Plugin.Plot.GetInstance(activity) from the OnCreate method of one of your activities.

Known issue for Android: When the Android Package name contains a dash or an underscore the mail debug log feature doesn't work. You can fix this by adding the following element to the application element of your AndroidManifest, with YOUR_PACKAGE_NAME replaced:

<provider
   android:authorities="YOUR_PACKAGE_NAME.plot.debuglogprovider"
   android:name="com.plotprojects.retail.android.DebugLogProvider"
   android:exported="true" />

When your android package name doesn't contain any special characters, no steps are required.

 

Step 4: iOS Step Only

You can skip this section when your app doesn't need iOS support.

Place plotconfig.json in the Resources folder of your project. You can configure Plot through the configuration file. You can find an example config file and your public token on the Developer page on our dashboard.

 

Step 5: iOS Step Only

Add the following line to your FinishedLaunching method in your AppDelegate:

PlotProjects.Plugin.Plot.GetInstance(launchOptions, true);

 

Step 6: iOS Step Only

Also copy the following snippet to your AppDelegate:

public override void ReceivedLocalNotification (UIApplication application, UILocalNotification notification)
{
    PlotProjects.Plugin.Plot.HandleNotification (notification);
}

 

Step 7: iOS Step Only

Add the property "Location Always Usage Description" in Info.plist with as value a message for your users describing why your app uses the location of the device. This can be done in the Info.plist file while selecting the source tab. The description could be for example: "Your location is used to instantly inform you when you are near a location that is interesting to you." This description text is shown when permission to use the location of the device is requested via the opt-in dialog. Note that for the app to be accepted in the App Store, the description why the app needs location services must be clear to the end user.

You are now ready to receive your first notification. For more details, look at our Github page.

Need more help during testing, look at the testing section of the documentation.

Back To Top

7. Dashboard API

We offer an API to add and modify geofences (locations) and notifications (campaigns) for the Plot plugin. When you want to manage the notifications using a visual interface, then you can use our Dashboard.

Documentation about the API and the specific calls can be found at the full API documentation.

The API is located at the following URL: https://admin.plotprojects.com

All requests have a Basic Authentication header with the appId as username and the private key as password. You can find these under "Integrate Plugin" in our Dashboard.

All requests return content of type application/json in UTF-8 encoding. All PATCH and POST requests consume a body of type application/json in UTF-8 encoding.

Currently our API has a limit to the amount of request you can do of 10 per second. Exceeding this limit will result in an unsuccessful API call and an 429 Too Many Requests response.

Back To Top

8.1 iOS & Android Demo App Guide

Try Plot Projects For Yourself In Five Easy Steps

The Plot Projects Demo App enables you to:

  • Experience how easy it is to create and send geofencing notifications on your own device
  • Get acquainted with our simple and intuitive dashboard
  • Send yourself a notification without any coding!

 

1. Create An Account Or Log In

Create a free account on the Plot Projects website.

Directly after creating your account, you will be introduced to your "personal dashboard".

If you already have an account with Plot Projects, just go straight to your dashboard.

 

2. Download The Demo App

For iOS you can find the free Plot Projects Demo App in the Apple App Store.

For Android you can find the free Plot Projects Demo App in the Google Play Store.

 

3. Enter Your Token

To enable the Demo App to receive the push notification, enter the six digit token that appears on your screen.

Go to “Settings” in the Demo App, followed by "Connect To Account" and enter the six digit token.

At this point you will be prompted to allow Plot Projects to access you location information and to send you push notifications. Make sure to opt-in for both!

 

4. Create A Campaign

Click on the blue button on the bottom right corner. Choose "New Notification Campaign".

Enter a campaign name and notification message.

Scroll down the page to the section titled "select regions for this campaign". On the map, make sure to enter your current location. Once you have selected the location, you will notice a red circle appearing in the map. That's your geofence.

Then scroll to the bottom of the page and select "create" to set your geofence live.

 

5. Check Your Phone For a Notification

As soon as you enter the geofence, your phone will receive the notification message that you just created!

Back To Top

8.2 Notification Troubleshooting Checklist

Sometimes receiving your first notification can be difficult. There are some edge cases that arise especially during testing. To help you on the way we have created a checklist to help you figure out what might be going wrong and what is preventing you from receiving that first awesome notification on your phone!

We have created checklists, each explaining simple things to check;

  1. iOS Demo App
  2. Android Demo App
  3. iOS Plugin
  4. Android Plugin

1. iOS Demo App

Check these points when you are not receiving your notification on the iOS Demo App.

1. Did you create a geofence and a notification on your current location? This can be done in our dashboard. Make sure to set the range of the geofence large enough (> 200m for testing purposes).

2. It can take some time before the demo app on your device is synchronized with our server. To quickly sync your device you could reinstall the app as it will force a sync. After a reinstall the app has to be opened. If you are in the geofence and still want to receive a notification you have to bring the app to the background immediately after opting in to location services.

3. If you are already in the geofence and have the app in the foreground, you won't receive a notification, but it will show up in the notification tab of the demo app itself. If you want to see the notification in the iOS Notification Center, bring the app to the background straight after opting in.

4. Is the notification enabled? When the notification is set to paused it cannot be received.

5. Make sure it doesn't have opening hours or timespans. You can let the notification trigger anytime by setting "Notification can be triggered at the following times:" to "any time" in the advanced settings of your campaign.

6. Did you set the demo token correctly? It is the 6 digits number that was displayed to you after signing up. If you missed that, you can retrieve it from the developer tools tab of your dashboard. You can set the token in the Settings tab of the Plot Projects app and then click on Connect to account. Once you've entered the demo token the demo app will remember the token.

7. Do you have location services on for the demo app? This can be done in two ways; You will be prompted to enable this after filling in your token, or you can set it at Settings > Plot Projects > Location > Always

8. Are location services enabled on the device? You can set it at Settings > Privacy > Location Services. There you can set Location Services to On.

9. Do you allow our app to send you notifications? This can be done in two ways; You will be prompted to allow this after filling in your token, or you can set it at Settings > Plot Projects > Notifications > Allow

10. Do you have an internet connection? In order to load your notifications and geofences the demo app requires a working internet connection. A continuous internet connection also improves location accuracy.

11. Is WIFI enabled? Although no WIFI connection is required, it improves location detecting accuracy.

12. Did you already receive the notification before? Make sure the notification is set to be received more than once in the campaign settings in the dashboard.

13. Is there an app cooldown specified? When there is a cooldown specified in our dashboard for your app then the Plot plugin won't sent more than one message during the specified period. Set the minimum time to "upon re-entering" to remove any cooldown.

14. Have you stayed at the same location for a long time? The Plot plugin works best when moving at slower speeds. To optimize for battery efficiency it is possible you don't receive a notification when driving a vehicle or staying for a longer period on the same location.

15. Is the notification you are not receiving an beacon notification? Please make sure you have turned bluetooth on.

16. Still didn't receive your notification? You can find more detailed information in the log file. You can mail the log file by pressing "Mail log" in the Settings tab.

2. Android Demo App

Check these points when you are not receiving your notification on the Android Demo App.

1. Did you create a geofence and a notification on your current location? This can be done in our dashboard. Make sure to set the range of the geofence large enough (> 200m for testing purposes).

2. It can take some time before the demo app on your device is synchronized with our server. To quickly sync your device you could reinstall the app as it will force a sync. After a reinstall the app has to be opened. If you are in the geofence and still want to receive a notification you have to bring the app to the background immediately after opting in to location services.

3. Is the notification enabled? When the notification is set to paused it cannot be received.

4. Make sure it doesn't have opening hours or timespans. You can let the notification trigger anytime by setting "Notification can be triggered at the following times:" to "any time" in the advanced settings of your campaign.

5. Did you set the demo token correctly? It is the 6 digits number that was displayed to you after signing up. If you missed that, you can retrieve it from the developer tools tab of your dashboard.You can set the token in the Settings tab of the Plot Projects app and then click on Connect to account. Once you've entered the demo token the demo app will remember the token.

6. Have you turned on location services? You can usually set this at Settings > More > Location services. The mode should be High Accuracy or Battery saving.

7. Do you have an internet connection? In order to load your notifications and geofences the demo app requires a working internet connection. A continuous internet connection also improves location accuracy.

8. Is WIFI enabled? Although no WIFI connection is required, it improves location detecting accuracy.

9. Did you already receive the notification before? Make sure the notification is set to be received more than once in the campaign settings in the dashboard.

10. Is there an app cooldown specified? When there is a cooldown specified in our dashboard for your app then the Plot plugin won't sent more than one message during the specified period. Set the minimum time to "upon re-entering" to remove any cooldown.

11. Have you stayed at the same location for a long time? The Plot plugin works best when moving at slower speeds. To optimize for battery efficiency it is possible you don't receive a notification when driving a vehicle or staying for a longer period on the same location.

12. Is the notification you are not receiving a beacon notification? Please make sure you have turned bluetooth on.

13. Still didn't receive your notification? You can find more detailed information in the log file. You can mail the log file by pressing "Mail log" in the Settings tab.

3. iOS plugin

Check these points when you are not receiving your notification on your own app with Plot integrated.

  1. Did you receive a notification when using the demo app? If not, see the iOS Demo App checklist.
  2. Did you do all the steps in the iOS integration guide correctly?
  3. Did you use the most recent version of our plugin?
  4. Is plotconfig.json correctly added? An example of this file can be seen at the Developer Tools in our dashboard.
  5. Did you set the public token (not the demo token!) inside the plotconfig.json? The public token can also be found on the dashboard.
  6. When the app is in the foreground the notification doesn't appear in the notification center, but is directly opened by the app.
  7. Does your app use its own notification filter? Are you sure the implementation is correct? You could try removing the filter to verify that the notification is not filtered out.
  8. You can check the debug log, which can be sent from the demo app. This is also possible from the plugin, see this blog post.
  9. In case you are still not receiving a notification, you could try to uninstall and reinstall the app.

4. Android plugin

Check these points when you are not receiving your notification on your own app with Plot integrated.

  1. Did you receive a notification when using the demo app? If not, see the Android Demo App checklist.
  2. Did you do all the steps in the Android integration guide correctly?
  3. Did you use the most recent version of our plugin?
  4. Is plotconfig.json correctly added? An example of this file can be seen at the Developer Tools in our dashboard.
  5. Did you set the public token (not the demo token!) inside the plotconfig.json? The public token can also be found on the dashboard.
  6. Does your app use its own notification filter? Are you sure the implementation is correct? You could try removing the filter to verify that the notification is not filtered out.
  7. You can check the debug log, which can be sent from the demo app. This is also possible from the plugin, see this blog post.
  8. In case you are still not receiving a notification, you could try to uninstall and reinstall the app.

If you are still not receiving any notifications, please check our documentation or contact us through the dashboard. Please have your log file ready.

Back To Top

8.3 Segmentation Guide

Location based notifications are already more relevant than push notifications, but to further improve the relevancy of your notifications you can segment your users. The segmentation feature allows you to limit specific notifications to specific groups of users. This prevents your end users from receiving notifications that aren't relevant for them. This feature is introduced in version 1.10.0 of our plugin.

You can specify in your app to what segment the device belongs and in the dashboard you can define what segments should receive the notification.

Segmentation Properties In Dashboard

You can specify in notifications and campaign notifications what segmentation properties must have been set on the device before the device can receive these notifications. When a property that is set on the notification isn't set on the device or the property on the device has a different value than on the notification, then the notification isn't sent. This is also the case for apps with an older version of the Plot Plugin that doesn't have support for segmentation. Segmentation properties set on the device, but not on the notification or campaign are ignored.

The segmentation settings for a notification are under the Advanced Settings. By default all devices can receive a notification.

Device Properties

Before users can receive segmented notifications you have to specify to what segment the user belongs. Both on iOS and on Android the Plot class has methods that allow setting the segments the user belongs to. When you specify a new value for a segmentation property that is already defined, the old value is overwritten with the new value.

All currently loaded notifications on the device will be removed when calling one of the segmentation property methods. The next data update will contain all appropriately segmented notifications.

There is a specific method for each property type. Currently the supported types are integer (numeric values), double (numeric decimal values), string (text values), date (UNIX timestamp) and boolean (true or false). Below is an example snippet for each platform on how to set the segment gender to male on the device.

Example iOS snippet:

[Plot setStringSegmentationProperty:@"M" forKey:@"gender"];

Example Android snippet:

Plot.setStringSegmentationProperty("gender", "M");

Example Appcelerator/Phonegap snippet:

plot.setStringSegmentationProperty("gender", "M");

The Segmentation chapter further explains segmentation in a technical way and examples per type can be found for iOS, Android, Appcelerator and Phonegap.

It is currently not yet possible to specify segments in our test apps that are available through the Play Store or the App Store.

Segment On Campaign History

When you set the property type to “campaignhistory” you can segment on users who have, or haven’t, triggered a (geotrigger)campaign earlier. You can for example use this feature to send notifications to users that have been to your store earlier or to a store of a competitor.

You specify a Campaign Id segmentation property in the dashboard just like device properties. You have to specify the campaign id, the number of times the user has triggered that campaign and in what time frame these triggers must have occurred. You do not have to set any properties for this on the device.

The Segmentation chapter further explains this in a technical way.

Custom Reporting

For customers with our Gold or Platinum plan it is possible to make the segments you define in your app part of your custom reports. Contact us for more information.

Back To Top

8.4 Attribution Campaign Guide

Plot Projects already provides the possibility to analyze the location data of your users by using Geotrigger campaigns through the dashboard. Geotriggers are used for monitoring user behaviour in Geofence or Beacon regions e.g. time spent, number of visits, etc. With these campaigns we can effectively measure foot traffic at your locations.

In order to extend the possibilities provided by this type of campaigns and to further refine their usability, we have restructured the types of geotrigger campaigns we provide to Data campaigns which are distinguished in Listening campaigns and Attribution campaigns. Regular Notifications campaigns remain unchanged in terms of functionality.

Data Campaigns

Data campaigns is our new term to describe campaigns that are not used to show Notifications to the users' devices as opposed to Notification campaigns. They only gather insights concerning the user's location activity.

Data campaigns include two sub-types of campaigns. Those are Listening campaigns and Attribution campaigns.

Listening campaigns were called Geotrigger campaigns previously. Attribution campaigns are the new type of campaigns that will be described next in details.

Attribution campaigns in the Dashboard

Attribution campaigns can be used to measure the effectiveness of your online campaigns. This is done by linking actions done by the app's user to the actual user's location changes. For example, attributing a user's visit to a store to his action of seeing or opening a coupon in app.

In order to create an Attribution campaign in the dashboard, an attribution action need to be determined. This action can be the user reading a flyer or seeing a coupon inside the app, etc. This information is sent through our plugin so that it can be reported back to you. Please note that it is important to be consistent in naming the action in the dashboard and in your app so we advise you to do this in cooperation with your development team to make sure the correct user action is tracked.

In the "Create Attribution campaign" page in the dashboard, under "Attribution Campaign Options", you can set "Action name", "Item Identifier" and "Minimum dwell time to count as an Attribution". Action name and minimum dwell time are required fields while item identifier is optional. Item identifier refers to the exact item that is linked to the attribution, e.g. a flyer or coupon identifier.

An extra possibility offered by Attribution campaigns is that through these campaigns we can report based on the time the user spent in the geofence of interest. For instance, how long on average users stay in the store location.

Implementing Attribution Campaigns

We support attribution campaigns for geofences and beacons.

Both on iOS and on Android the Plot class has methods that allow sending attribution events. Below is an example snippet for each platform.

Example Android snippet:

Plot.sendAttributionEvent("read_flyer", "discounts_week_12");

Example iOS snippet:

[Plot sendAttributionEvent:"read_flyer" withItemId:"discounts_week_12"];

In the dashboard, in order to be able to report on the "discount_week_12" flyer, you will need to specify the same setting for action name and item identifier, as shown below.

Custom reporting

After creating Attribution campaigns, it is possible to set up the report deliveries in cooperation with your customer success manager. Reports can be delivered through the Custom Reports tab in the dashboard, Google Storage, Amazon S3 or to a BigQuery dataset.

Clients with a gold plan or higher have access to the Attribution campaigns feature through the dashboard. Contact your Customer Success Manager or Contact us via the contact form for more details.

Back To Top

9. Glossary

This page provides a list of terms that are specific to our platform:

Appcelerator
Appcelerator is the company behind Titanium. For more information see their homepage.
AppDelegate
An object in iOS responsible for handling state transitions within your app. The delegate is responsible for initialization of the app and receiving of notifications. For more information see the iOS Programming Guide.
A link to another app, this can be triggered when tapping on a notification. Settings for this have to be put into the data field and the handlerType has to be set to applink.
App Store
A platform provided by Apple to distribute your app on iPhones and iPads.
Background mode
A marker that your app wants to continue running in the background (iOS only). A distinction is made between various background modes. Plot doesn't require a background mode to function. Get more information from the iOS Programming Guide.
Background services
Get more information from the Android documentation.
Broadcast receiver
For more information see Android Reference.
Campaign
A campaign is a notification attached to a set of geofences. The notification message might be different per geofence by using the geofence label. A campaign makes maintaining notifications easier by not having to define a notification for each geofence.
Cellular Triangulation
A battery efficient technique to determine the location of the device based on the cellular networks the device uses. This technique is available for all iPhones, and for iPads and Android devices that can make use of cellular networks.
Cooldown period
The minimum time between two notifications. This period is to prevent users to get a flood of notifications.
Cordova
Apache Cordova is a platform to build platform independent apps. Plot has provided a module for this platform to make integration trivial. Get more information from their website.
Country field
You can attach a campaign to a country. The field has to be set with a three-letter country code, a list of available codes can be found here.
Custom region field
A custom region field should be defined inside your app settings. Specify custom region fields for a geofence or beacon which can be used later as placeholders in the campaign message. For instance, you can create a field shopname that will contain the shop name for each geofence. Using it inside the campaign message allows you to mention the shop name depending on which geofence gets triggered. The field names are case insensitive and cannot contain duplicates.
Data field
Contains your own custom data which you could use inside a notification/geotrigger handler or notification filter. You can get this data inside your app by getting the data attribute from the notification or geotrigger. If the data field contains an URI starting with http or https and no handler is created by the user the data field will be opened in the app browser as URI. The data field can also be used to set a landing page or an applink.
Data update
An update of the notifications cached in the device. Notifications that can be sent by a device are cached locally to prevent network usage at every location update.
Datetime
A combination of a date and time.
Dwelling notifications
A notification that is sent when the user remains within the geofence or beacon region for a specified amount of time. The time is adjustable per notification and must be between 5 minutes and 12 hours.
Exit notifications
A notification that is sent when the user leaves the geofence or beacon region.
Framework
A framework allows you to build platform independent apps. You write code once and compile both Android and iOS. Currently we support three frameworks; Appcelerator (Titanium), Cordova / Phonegap and Xamarin.
Geofence
A location with a radius that you can send notifications for.
Geotrigger
A geotrigger is used to see if users enter or exit a geofence or gets into or leaves the range of an iBeacon. It works similarly as a notification, but it does not display anything on the device of the user.
Geotrigger campaign
Similar to a campaign for notifications, this is a campaign for geotriggers on multiple geofences. This makes it easier to maintain and evaluate your sets of geofences.
GPS
A technique to determine the location of the device. This technique is accurate, but isn't very battery efficient. Because it isn't very battery efficient, Plot doesn't make use of this technique.
iBeacon
A device that broadcasts using Bluetooth 4.0 to allow indoor positioning.
Intent
A technique for Android to perform inter-process communication. An Intent is a message from one app to another. For more information see the Android Development Guide.
Ionic
Ionic is a platform to build platform independent apps. It is built on top of Apache Cordova and AngularJS. Plot has provided a module for Cordova, thus we also support Ionic. More information on Ionic can be found on their website.
iOS
The operating system that runs on iPhones and iPads.
Landing page
An HTML page shown when a notification is triggered. The link to the landing page should be set inside the data field and the handlerType to landingPage. In-app landing pages bypass the notification filter and the notification handler.
Local notification
A notification sent directly from an app. This notification doesn't require a remote server, therefore can be viewed instantly on the device.
Location based notification
A notification sent to a user based on their current location.
Location services
The service offered by Android and iOS that provides the current location of the device to apps.
Notification center
The area in the user interface of iOS where the notifications are shown.
Notification events
Events sent by our plugin each time a notification is shown to the user (sent) or tapped on by the user (opened).
Notification filter
An optional callback in Plot that can be used to prevent notifications from being shown or modify the notifications before they are viewed to the user.
Notification handler
An optional callback in Plot that can be used to change the action when a notification is tapped.
PhoneGap
A platform, based on Cordova, to build platform independent apps. Plot has provided a module for this platform to make integration trivial. Get more information from their website.
Play Store
A platform provided by Google to distribute your app on Android devices.
Private token
A token provided by Plot that provides authorization to maintain geofences and notifications. You must not use this token inside your app.
Proguard
Proguard is a tool for Android to obfuscate and optimize your Java classes. This tool makes it harder to decompile your code.
Public token
A token provided by Plot that is used inside your app to obtain notifications.
Push notification
A notification sent from a remote server. Plot doesn't make use of this technique, because it could take minutes before a notification that has been sent is received by a device. The notification may then be no longer relevant.
QuickSync
An improved way to synchronise your app users' devices with our server. Instead of letting your users' devices poll for changes, new or updated notifications get actively pushed upon change. More information can be found here.
Sent notification
When Plot detects that a user is in a Geofence and no constraints prevent the notifications from being sent, then the notification is sent. A Sent notification may or may not have been viewed by the user.
Significant location change
A technique available in iOS to determine when the device has moved significantly. This technique is very energy efficient, but very inaccurate and unpredictable. Plot doesn't make extensive use of this technology.
Titanium
A platform by Appcelerator to build platform independent apps. Plot has provided a module for this platform to make integration trivial. Get more information at their website.
Trigger times
Which time mechanic is used for the notification, this can be inherit, where the notification will use its Geofence or iBeacon time settings, it can be anytime, being active at any time, timespans, where it uses custom defined time spans, and openinghours, which are repeated time spans defined for a week.
Viewed notification
After a notification is sent, a user may tap on a notification. When a user has tapped on a notification, the corresponding action is executed and the notification is marked viewed.
Wifi triangulation
A battery efficient technique to determine the location of the device based on Wifi. The device detects what Wifi access points are available in the current area and compares those with the database maintained by Google (in case of Android) or Apple (in case of iOS). For this technique to work, the device needs to have internet access, but the device doesn't require access the these Wifi access points.
Xamarin
With Xamarin it is possible to do Android and iOS in C# with either Visual Studio or Xamarin Studio. This allows you to re-use existing C# code, and share code across device platforms.

Back To Top