BurtTracker is a static library for iOS that enables sending tracking data to Burt’s servers. It is currently in a beta state, and changes to the interface might occur in future releases.
This documentation describes the most recent version of the library, v0.2.0.
The library is distributed as a fat library, built for ARM64, ARMV7, ARMV7S,
i386, and x86_64, with iOS 7.0 as the deployment target. The distributed
archive contains this library (libBurtTracker.a
) as well as the necessary
header files.
The BTTracker
class represents the entry point to the library. An instance of this class is configured with a tracking key obtained from Burt through a BTOptions instance. The tracking key attributes and identifies the traffic source. A single BTTracker
instance is meant to be shared through the lifetime of the app invocation.
From this BTTracker
instance one or more instances of BTScreenTracker
are created to track views. In many cases, a view can be thought of as a page view in terms of web tracking, and most often the life cycle of the tracked view corresponds to that of the actual app view. The SDK does not dictate any specific model and depending on the structure and flow of your specific app you may want or need to define a view differently. In general, we recommend to try to keep only one BTScreenTracker
started simultaneously. Please don’t hesitate to contact your Burt representative when considering the model for your specific use-case.
The first step is to initialize the BTTracker
. This is ideally done when the app is loaded as to ensure subsequently added screen trackers can access the configured instance.
In the application setup:
This will create a singleton instance with the given options. The instance can then be accessed through [BTTracker tracker]
.
For each view you want to track, create and start a screenTracker
when the view is loaded:
The CONTENT_ID
should uniquely identify the tracked content. If there is a web page corresponding to the same content, it is recommended to use that URL as CONTENT_ID
, in order to make analysis across multiple sources easier.
The end of a view is indicated by stopping the BTScreenTracker
:
Subsequent attempts to start and stop a BTScreenTracker
will have no effect.
In order to track long lived sessions, for example to allow collection of durations and metadata made available throughout a session, the session must be kept alive by pinging the backend continuously. This is not done automatically by the screen tracker, but instead the ping scheduling process is handled by a separate instance of BTPingScheduler
. The BTPingScheduler
constructor takes an instance of a BTScreenTracker
and can be configured to use a custom schedule. This gives more control of when to start the ping scheduling process and how often pings should be sent.
The recommended approach is to start and stop the ping scheduler together with the associated screen tracker as illustrated in the following code.
Depending on the use-case, it might be desirable to let a view continue when the user puts the application in the background.
If this is the case, the ping process must continue to keep it alive. A background process must be started when the application enters the background to allow this.
If it is not important to capture the time in the background we recommend stopping the screen tracker when the application enters the background and, if desired, simply start a new screen tracker when the application resumes. Note that this will result in two separate view objects.
The SDK measures the total duration and active duration of views. In terms of screen tracking the total duration is simply the duration between starting and stopping a BTScreenTracker
. The active duration is meant to model the duration during which the user is actively engaged with the content.
The app must indicate to the BTScreenTracker
when the user becomes active (e.g. when the user scrolls the content of a view or causes a touch event) or becomes inactive (e.g. when the user switches to another app) in order for the SDK to update the activity state of the session. The activity state of the session is changed through the screen tracker using the signalUserActive
/signalUserInactive
methods as follows:
When a screen starts, it will initially be inactive. If no activity signals are sent before stopping the screen tracker, the active duration will be zero.
When signalUserActive
is called, the SDK will start to attribute time to active duration. This method must be called continuously as long as user interactions are detected to extend the active duration. The default behavior is that once signalUserActive
has not been called for 60 seconds, a timeout will be reached and the screen will be considered inactive. At this point, the active duration will also be compensated to not include the time since the last indication of user activity.
Furthermore, every screenTracker
allows the user an initial grace period called the time-in period (default is 30 seconds) that is meant to capture a lower rate of user interaction during content loading and reading the first few paragraphs of text in the view. If the user becomes active within the time-in period after the screen tracker is started, the time preceding the activity signal is attributed to the active duration.
When signalUserInactive
is called the user is immediately considered inactive and active duration will not be attributed until the next signalUserActive
call.
Several cycles of active and inactive states are allowed within the same screen. The following gives an example time line for a screen where the user has clicked a link to an article view:
[screenTracker start]
[screenTracker signalUserActive]
[screenTracker signalUserInactive]
[screenTracker signalUserActive]
[screenTracker signalUserActive]
[screenTracker stop]
Associating additional meta data to the view is done through annotations (see the glossary for more info).
For instance, if the view corresponds to an article and you want to associate the author to the article, you can annotate the information as follows:
Annotations can be added to a view anytime during the full life cycle of the BTScreenTracker
, but no requests will be sent before starting the screen tracker. All annotations triggered before starting the tracker will be sent when the tracker is started, and all annotations triggered after the tracker is stopped will be ignored.
Profiles are fetched asynchronously, thus to retrieve profile information about the user you have to implement a delegate to handle the asynchronous response:
And in the application setup code, do
This implementation would log the profile ID along with the segments the user belongs to to the console. If the user hasn’t been seen before, the returned profile ID will be nil
and the segments array empty.
The initialization of the tracker in the example above uses the most basic setup, but the tracker can be configured further to give a more fine grained control of the tracking.
The BTTracker
configuration is described by the BTOptions
instance supplied when initializing the tracker, see BTOptions for details of configurable parameters.
A test setup for the tracker could look like this:
Using this test setup, you’d get a tracker that logs requests and warnings to the console, allows user tracking and uses HTTPS as transfer protocol. However, since localMode is turned on, no actual requests will be sent to remote servers.
The screenTracker do also expose a more flexible interface, which allows you to add cloud keys (glossary for more info) and gives you control over when to start tracking. One can add cloud keys and start the tracker as follows:
It is important that the cloud keys are added prior to starting the screen tracker in order for the cloud keys to be connected to the screen. So, if the screen tracker was initiated and started using the shorthand [[BTTracker tracker] startNewScreenTrackerWithContentId:@"CONTENT_ID"]
, no additional cloud keys can be added to the tracker.
userTracking
(Property)localMode
(Property)debugLogging
(Property)protocol
(Property)activityTimein
(Property)activityTimeout
(Property)+ (instancetype)optionsWithTrackingKey:(NSString *)trackingKey
+ (instancetype)trackerWithOptions:(BTOptions *)options
+ (instancetype)tracker
- (BTScreenTracker *)screenTrackerWithContentId:(NSString *)contentId
- (BTScreenTracker *)startNewScreenTrackerWithContentId:(NSString *)contentId
- (void)profileWithDelegate:(id<BTProfileDelegate>)delegate
- (void)start
- (void)stop
- (BOOL)isStopped
- (void)signalUserActive
- (void)signalUserActive:(BOOL)persistent
- (void)signalUserInactive
- (void)ping
- (BOOL)addCloudKey:(NSString *)cloudKey
- (void)annotateWithScope:(NSString *)scope name:(NSString *)name value:(NSString *)value
- (void)connectWithScope:(NSString *)scope name:(NSString *)name value:(NSString *)value
intervals
(Property)deviationFactor
(Property)- (instancetype)initWithIntervals:(NSArray<NSValue*>*)intervals deviationFactor:(NSTimeInterval)deviationFactor
- (instancetype)initWithScreenTracker:(BTScreenTracker *)screenTracker
- (instancetype)initWithScreenTracker:(BTScreenTracker *)screenTracker schedule:(BTPingSchedule *)schedule
- (void)start
- (void)stop
- (BOOL)isStarted
- (void)profile:(NSString *)profileId belongsToSegments:(NSArray *)segments
- (void)didFailWithError:(NSError *)error
userTracking
(Property)A BOOL
property stating whether user tracking should be enabled or not. If user tracking is enabled, the id generated for the user will be persisted on the device and reused across screens and restarts (this is the default setting).
localMode
(Property)A BOOL
property stating whether local mode should be enabled or not. By default, local mode is not enabled. When local mode is enabled, no requests will be made to remote servers. This is only intended for use in a test environment as it effectively disables tracking.
debugLogging
(Property)A BOOL
property stating whether debug logging should be enabled or not. By default, debug logging is not enabled. When debug logging is enabled, the library will log certain information about what it does to assist with debugging. This is only intended for use in a test environment.
protocol
(Property)A BTProtocol
property defines which transport protocol to use for communication with Burt’s servers. The available options are BTHTTPS
(default) and BTHTTP
.
activityTimein
(Property)An NSTimeInterval
property defining the activity time-in period in seconds. If the user becomes active within this period after the screen tracker is started, the time preceding the activity signal is attributed to the active duration.
activityTimeout
(Property)An NSTimeInterval
property defining the activity timeout in seconds. If the user is inactive for longer than the activity timeout the screen will be considered inactive and active duration will not be attributed from this point. The active duration will also be compensated to not include the time since the last indication of user activity.
+ (instancetype)optionsWithTrackingKey:(NSString *)trackingKey
Creates a BTOptions
instance with the given trackingKey
and default
options.
+ (instancetype)trackerWithOptions:(BTOptions *)options
Sets up a BTTracker
which will be returned in all subsequent
[BTTracker tracker]
calls.
+ (instancetype)tracker
Returns the latest setup BTTracker
, or nil
if
trackerWithOptions:
hasn’t been called before.
- (BTScreenTracker *)screenTrackerWithContentId:(NSString *)contentId
Creates a BTScreenTracker
with the given contentId
. contentId
is any ID which you can use to identify what has been viewed, e.g. a URL or a CMS article ID.
- (BTScreenTracker *)startNewScreenTrackerWithContentId:(NSString *)contentId
Creates and starts a BTScreenTracker
with the given contentId
. See screenTrackerWithContentId:
.
Starting a tracker sends view data to Burt’s servers.
- (void)profileWithDelegate:(id<BTProfileDelegate>)delegate
Asynchronously retrieves information about the user and delegates the result to
the provided delegate
on completion.
- (void)start
Initiates the screen tracking. No requests to Burt’s servers will be made before calling this method. Calling it multiple times have no effect.
- (void)stop
Stops the screen tracker. After the screen tracker is stopped it can not be started again and all further interactions, such as annotations, will be ignored.
- (BOOL)isStopped
Returns YES
if the screen tracker is stopped, NO
if it is either started or not yet started.
- (void)signalUserActive
Indicate that the user is active. From the point that this method is called the user is considered active for one minute or persistently, depending on the value of persistent
.
- (void)signalUserActive:(BOOL)persistent
Indicate that the user is active. From the point that this method is called the user is considered active for one minute or persistently, depending on the value of persistent
.
When persistent
is false
and if no further calls are received within one minute the screen is automatically transitioned to inactive. For each further call within one minute the timeout is reset. Thus, a screen will stay active as long as a call occurs at least every minute. We recommend using this mode when continuous interactions are required to consider the screen active. For example, the following events typically indicate user activity and are appropriate times to indicate activity:
Depending on the layout and structure of your particular app some of these may not apply or there may be additional events.
When persistent
is true
the active state remains until either #signalUserActive:NO
, #signalUserInactive
or #stop
is called. We recommend using this mode when the screen is to be considered active regardless of continuous interactions from the user. For example, when a user starts a video clip within the screen it may be desired to use this mode so that the complete duration of the video is attributed as active. In other cases, the mere presence of a screen may be sufficient to indicate the user is actively engaged.
Consult your Burt representative for guidance on working with these modes and what events may be appropriate for your app.
- (void)signalUserInactive
Indicate that the user is inactive, i.e. absent from interaction with the content. This method shall be called when the user has triggered an event that is a clear indication of the user being absent. Here are some examples of appropriate events:
- (void)ping
Sends a ping fragment containing the current durations. This could be used to build a custom ping scheduler, see BTPingScheduler or section about ping scheduling for more information.
- (BOOL)addCloudKey:(NSString *)cloudKey
Adds a cloud key to the screen tracker. Cloud keys follow a specific format and are supplied by Burt. You should only call this method once per Burt supplied cloud key, and calls to this method will be ignored if the screen tracker has been started or if the cloud key does not conform to a specific format. The returned BOOL
indicated whether the cloud key was added or not.
- (void)annotateWithScope:(NSString *)scope name:(NSString *)name value:(NSString *)value
Sends an annotation to the Burt API, associated with the current view. If this method is called before starting the screen tracker, the actual request will be delayed until it has been started. Any calls to this method after the tracker is stopped will be ignored. For more information about annotations, please refer to the glossary.
- (void)connectWithScope:(NSString *)scope name:(NSString *)name value:(NSString *)value
Works like - annotateWithScope:name:value:
, but sends a
connection rather than an annotation.
intervals
(Property)An NSArray<NSValue*>*
that defines a base schedule of time intervals in seconds between each sent ping fragment. If the number of sent ping fragments exceeds the length of the schedule the last interval is used continuously.
deviationFactor
(Property)A double
that defines the maximum deviation factor for the intervals between pings. Each random interval intervals[i]
is within the bound intervals[i] +/- intervals[i] * deviationFactor
.
- (instancetype)initWithIntervals:(NSArray<NSValue*>*)intervals deviationFactor:(NSTimeInterval)deviationFactor
Creates a new ping schedule with the given intervals
and deviationFactor
.
The BTPingScheduler
triggers pings periodically on the associated BTScreenTracker
.
- (instancetype)initWithScreentracker:(BTScreenTracker *)screenTracker
Creates a new ping scheduler with the default settings. These default settings are optimized for most standard use-cases with respect to providing a balance between guaranteeing keeping sessions alive and minimizing the number of pings sent. This is the recommended constructor.
- (instancetype)initWithScreenTracker:(BTScreenTracker *)screenTracker schedule:(NSArray<NSValue*>*)schedule deviationFactor:(NSTimeInterval)deviationFactor
Create a new ping scheduler with a given BTPingSchedule
. We do not recommend using this constructor without first consulting with your Burt representative, to ensure delivery and accuracy of the tracking data.
- (void)start
Starts the ping scheduler. Ping fragments will be sent within intervals according to the schedule
and deviationFactor
from this point until either the ping scheduler or the screen tracker is stopped. Calling it multiple times have no effect.
- (void)stop
Stops the ping scheduler. No ping fragments will be sent from this point.
The ping scheduler will cease to schedule and send additional ping fragments after the screen tracker is stopped, but it is recommended to stop the ping scheduler manually when that happens to avoid a last unnecessary wake up 0-60 seconds after the screen tracker is stopped.
isStarted
Returns a BOOL
that is YES
if the ping scheduler is started and NO
if it is stopped.
Errors in the SDK will have the domain BTErrorDomain
and one of the
following codes:
BTErrorRetriable
A retriable error occurred, e.g. because a resource was temporarily down or something timed out. The operation can be retried at a later time.
BTErrorBadInput
The supplied input was incorrect, please refer to the documentation for the performed operation. The operation should not be retried without first changing the input arguments.
BTErrorUnknown
An unexpected error has occurred. The operation should not be retried, and our support should be contacted if the problem persists.
- (void)profile:(NSString *)profileId belongsToSegments:(NSArray *)segments
This delegate method will be called when information about the profile has been
successfully fetched. profileId
is a unique ID for the current user, which
may be nil
if the user could not be found. segments
is an array containing
all segments the user belongs to.
- (void)didFailWithError:(NSError *)error
If unable to fetch profile information for some reason, this delegate method
will be called. Please see the section about BTError
for
information about error
.