Initial SDK setup
Minimum setup
To get started, you need to perform the following tasks:
This document will cover app setup and the component installation process, as well as basic integration steps for iOS and Android.
SDK Versions
The FollowAnalytics PhoneGap/Cordova SDK was tested on Cordova v6.+ and it includes versions 5.0.2 (iOS) and 5.0.8 (Android) of the FollowAnalytics SDK.
For an example, check out our PhoneGap sample integration code on Github.
Install the SDK
- Download the FollowAnalytics SDK from the developer portal.
Windows CI Workflows
If you're using a Microsoft Azure CI server please use the version inside the ci-version
folder of the downloaded .zip. This version fixes a problem related to iOS Framework symlinks.
- Use the
cordova
CLI to add the plugin to your app:
cordova plugin add /path/to/fa-sdk-phonegap-plugin/standard-version
Initialize the SDK
Add the following to your index.js
:
onDeviceReady: function() {
FollowAnalytics.initialize(YOUR_API_KEY);
}
Debug mode
Remove Debug mode before releasing
Don't forget to remove the debug flag when compiling to the stores in order to reduce logging whithin clients applications.
Register for notifications
iOS
If your app code is already registered to send push notifications, nothing to do here. Otherwise, simply add a call to registerForPush
, either from your HTML code whenever you think the moment has come to ask the user for it.
HTML
<a href="#" onclick="FollowAnalytics.registerForPush()">register for push</a>
Android
Build in release mode
The app must be built in release mode in order to receive push notifications
Logging
Data sent in debug mode will not appear on dashboards
When your app runs in DEBUG mode or in a simulator, the data is automatically sent as development logs, and is therefore not processed to be shown on the main UI page. DEBUG logs can be checked using the method given in the FAQ section.
See related entry in FAQ for more information on debug & release modes.
Logging best practices
To ensure your tags are relevant and will end up empowering your team through FollowAnalytics, please read the Logging best practices entry in the FAQ section.
Events vs Attributes
The FollowAnalytics SDK allows you to tag both events and attributes. If you are unsure about the difference, please refer to the corresponding FAQ entry.
Tag events
The SDK allows you to log events happening in your code. These are the two methods you can call on the SDK:
<a href="#" onclick="FollowAnalytics.logEvent('My event', 'My event details')">Log an event</a>
<a href="#" onclick="FollowAnalytics.logError('My error', 'My error details')">Log an error</a>
Use the name as the unique identifier of your tag, use the details section to add specific details, context. Events can be renamed later: the name that you give to your event here can be overridden in the FollowAnalytics UI.
The details field can either be a String or a Hash, so that you can associate multiple key-values for additional context.
For instance, logging the appearance of a view could be done the following way:
FollowAnalytics.logEvent('Product view', Product reference);
FollowAnalytics.logEvent('Add product to cart', {'product_id': 'ABCD123',
'product_category': 'Jeans'});
User ID and attributes
You don't need a user ID to set attributes
Attributes are tied to the device when no user ID is provided. If a user ID is set, a profile is created and can be shared across apps.
In both cases, attributes can be used in segments and campaigns to target users.
User ID
If users can sign in somewhere in your app, you can specify their identifier to the SDK. This way, you will be able to relate crashes to specific users, link your users between FollowAnalytics and your CRM, and more.
This identifier is usually an e-mail address, client identifier, phone number, or anything else that uniquely ties your customers to you.
To register the user identifier, use:
FollowAnalytics.setUserId("user_id@email.com");
FollowAnalytics.unsetUserID();
Predefined attributes
The SDK allows to set values for both custom and predefined attributes.
For predefined attributes, the SDK has the following properties:
FollowAnalytics.UserAttributes.setFirstName("Peter");
FollowAnalytics.UserAttributes.setLastName("Jackson");
FollowAnalytics.UserAttributes.setCity("San Francisco");
FollowAnalytics.UserAttributes.setRegion("California");
FollowAnalytics.UserAttributes.setCountry("USA");
FollowAnalytics.UserAttributes.setGender(FollowAnalytics.Gender.Male);
FollowAnalytics.UserAttributes.setEmail("mail@mail.com");
FollowAnalytics.UserAttributes.setBirthDate("2001-02-22");
FollowAnalytics.UserAttributes.setProfilePicture("https://picture/picture");
They are "predefined" in the sense that they will be attached to default fields on your user profiles.
Custom attributes
Double check your custom attribute types
When a value for an unknown attribute is received by the server, the attribute is declared with the type of that first value.
If you change the type of an attribute in the SDK, values might be refused server-side. Please ensure the types match by visiting the profile data section of the product.
Set a custom attribute
To set your custom attributes, you can use methods that are adapted for each type:
FollowAnalytics.UserAttributes.setNumber('key', "1");
FollowAnalytics.UserAttributes.setString('key', "A custom string attribute");
FollowAnalytics.UserAttributes.setBoolean('key', "true");
FollowAnalytics.UserAttributes.setDate('key', "2016-10-26");
FollowAnalytics.UserAttributes.setDateTime('key', "2016-10-26T11:22:33+01:00");
FollowAnalytics.setString("job", "Taxi driver");
Delete a custom attribute value
You can clear the value of an attribute using its key. For example, to delete the user's job:
FollowAnalytics.clear("job");
Set of Attributes
You can add or remove an item to or from a set of attributes.
To add an item:
FollowAnalytics.addToSet("fruits", "apple");
FollowAnalytics.addToSet("fruits", "banana");
FollowAnalytics.removeFromSet("fruits", "apple");
FollowAnalytics.clearSet("fruits");
Advanced Use Cases
Deep-linking: URL, Parameters
Campaigns created through FollowAnalytics allow to deep link to content in your app. You can either use an App Link, or use key-value parameters that are forwarded to your code.
App Links
Version 4.1.0 of the SDK introduced the possibility to use direct App Links like twitter://messages
, which will send you to the corresponding screen inside the Twitter application.
You're able to access the functionality by enabling the Deep Linking switch in our UI, when creating a campaign. There you'll find the field App Link that expects you to enter these type of url schemas. It can either be an URL Schema to an external application or for your own application.
Deep-linking parameters
In FollowAnalytics campaigns, you can specify deep-linking parameters, e.g. in your push messages or for in-app button actions.
These parameters are given to the developer's code by the SDK. It is then up to the developer to implement the deep-linking in the app (specific path of screens, format of the arguments, etc.).
iOS: Incoming notification
In order to be able to receive the custom parameters sent within a Push Notification or an In App message payload, you'll need to implement the followAppsShouldHandleParameters:actionIdentifier:actionTitle:completionHandler:
method. Inside your javascript files you'll have to implement a method that will be called from this Objective-C method. If you implement, or instance, a method called doAmazingThings()
as follows:
function doAmazingThings(args) {
console.log(args);
var currentdate = new Date();
var datetime = "Last Sync: " + currentdate.getDate() + "/"
+ (currentdate.getMonth()+1) + "/"
+ currentdate.getFullYear() + " @ "
+ currentdate.getHours() + ":"
+ currentdate.getMinutes() + ":"
+ currentdate.getSeconds();
document.getElementById('some_element').innerHTML = (datetime);
console.log('done');
}
You'll be able to call the doAmazingThings()
method using the following Objective-C code:
- (void)followAppsShouldHandleParameters:(NSDictionary *)openingParameters
actionIdentifier:(NSString *)actionIdentifier
actionTitle:(NSString *)actionTitle
completionHandler:(void (^)())completionHandler
{
if (actionIdentifier)
{
// here you'll have the identifier for custom push notification actions
}
if (completionHandler != nil) {
// always call the completionHandler, if any
completionHandler();
}
NSData *data = [NSJSONSerialization dataWithJSONObject:openingParameters
options:NSJSONWritingPrettyPrinted
error:nil];
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSString *functionCall = [NSString stringWithFormat:@"doAmazingThings(%@)", jsonString];
[YOUR_WEBVIEW_INSTANCE stringByEvaluatingJavaScriptFromString:functionCall];
}
iOS: Last notification
Some applications might not be able to receive the notification custom parameters. Although unlikely, you can call lastPushCampaignParams
form the native code to get the latest JSON containing the custom parameters passed by the Notification.
If you need to fetch this data from your javascript, use FALastPushMessageContent
, in response to the deviceready
event from Cordova/PhoneGap.
Please note that this is a one shot call, as a second call to this method will return an empty JSON.
iOS: Deep-linking parameters
In order to get the custom parameters sent with the Push Notification you'll need to implement the following method calls inside your index.js
file:
FollowAnalytics.deepLinkHandling = function(args) {
alert(JSON.stringify(args));
};
FollowAnalytics.retrieveLastMessage(function(args){
alert(JSON.stringify(args));
});
Since the Push Notification workflow differs when the application is on the background and when it's killed, you'll need to implement both method calls in order to be able to respond to each of those situations.
The args
content will be an object containing the keys and values you've defined in your Push Notification.
Android: Default behavior
By default, when the user clicks on a Push notification shown by the FollowAnalytics SDK, an Intent starting a new instance of your main activity is launched. You can retrieve any custom parameter in the Java code by adding the following lines in your onCreate
method.
@Override
protected void onCreate(Bundle savedInstanceState) {
Bundle extras = getIntent().getExtras();
if (extras != null) {
String value1 = extras.getString("a_custom_param_key");
String value2 = extras.getString("another_key");
// or retrieve all the pairs
for (String key : extras.keySet()) {
Object value = extras.get(key);
// …
}
// Do what you want with the custom values
}
}
Android: Handle deep-linking from Java
If you want more control, you can implement in your Java code the MessageHandler
interface, and declare it in your application class, like in the following example.
public class MyAwesomePushMessageHandler implements MessageHandler {
@Override
public void onPushMessageClicked(Context context, Map<String, String> data) {
String value1 = data.get("a_custom_param_key");
String value2 = data.get("another_key");
// Silently do stuff ...
// .. or start an activity
Intent intent = new Intent(context, SpecificActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
@Override
public void onInAppMessageClicked(Context context, String buttonText, Map<String, String> data) {
// Same as the above method, but from a in-app message !
}
}
If you define a custom MessageHandler
, you must declare it in your Application, after the FollowAnalytics.init(this)
line:
FollowAnalytics.setMessageHandler(new MyAwesomePushMessageHandler());
Android: Handle deep-linking from javascript
To handle the deep-linking from your javascript code, have this run when the device is ready:
onDeviceReady: function() {
...
FollowAnalytics.handleDeeplink();
FollowAnalytics.on("onPushMessageClicked", function(data){
alert(JSON.stringify(data));
});
FollowAnalytics.on("onPushDeeplinkingClicked", function(data){
alert(JSON.stringify(data));
});
FollowAnalytics.on("onInAppMessageClicked", function(data){
alert(JSON.stringify(data));
});
...
},
onPushMessageClicked
, onPushDeeplinkingClicked
and onInAppMessageClicked
.
- PushMessageClicked: When the user clicks on the push, you can retrieve all the added parameter as following:
FollowAnalytics.on("onPushMessageClicked",function(data){
//The argument data is an object Json.You can retrieve your value by data.my_key key/value json
});
- onPushDeeplinkingClicked: When the user clicks on the push, you can retrieve the url as follows:
FollowAnalytics.on("onPushDeeplinkingClicked",function(data){
//var my_url = data.url;
// And do something with it
});
```
* **onInAppMessageClicked**: When the user clicks on the the in-app button, you can retrieve all the added parameters as follows:
```javascript
FollowAnalytics.on("onInAppMessageClicked",function(data){
//The argument data is an object Json.You can retrieve your value by data.my_key key/value json;
//the label of button clicked is data.button;
});
The argument `data` is the javascript key-value object, you can retrieve the value by the key as following : `data["deepurl"]`
Control over campaigns
Custom handling of rich campaigns
Rich campaigns can be handled directly by the application code, instead of being showed automatically by the SDK. The behavior is defined when creating the campaign, using the "automatically display content" switch.
iOS
For campaigns where the content is not handled by FollowAnalytics, implement the following FAFollowAppsDelegate method in your AppDelegate:
- (void)followAppsShouldHandleWebViewUrl:(NSURL *)url withTitle:(NSString *)webviewTitle;
Android
For campaigns where the content is not handled by FollowAnalytics, you will need to extend com.followapps.android.CustomRichCampaignBaseReceiver
and declare it in your AndroidManifest.xml
.
You'll need to use an intent-filter on BROADCAST_RICH_CAMPAIGNS_ACTION
. For instance:
<receiver android:name=".RichCampaignDataReceiver" >
<intent-filter>
<action android:name="%YOUR_APP_PACKAGE_NAME%.BROADCAST_RICH_CAMPAIGNS_ACTION" />
</intent-filter>
</receiver>
%YOUR_APP_PACKAGE_NAME%
is your application package name.
The method onRichCampaignDataReceived
must be overridden. Rich campaign parameters are provided as method arguments:
- Campaign title:
title
- Campaign URL:
url
- Custom Parameters associated to the campaign:
customParams
Pausing in-app campaigns
You can prevent in-app campaigns from being displayed on certain views of your app. This can be useful when you are displaying a media content, or if the topmost screen is only shown for a few seconds, for instance.
Any campaign supposed to be displayed when the mechanism is paused is stacked and shown as soon as it is resumed.
To tell the SDK to prevent the display of rich campaigns, and then to activate it back, use the following methods:
FollowAnalytics.pauseCampaignDisplay();
FollowAnalytics.resumeCampaignDisplay();
Tip: use view lifecycle methods
If you want to prevent the display on a given page, you can call the pause method when a view appears, and the resume one when it disappears.
Tip: only allow display in some places of the app
You can use these methods the other way round, by pausing all campaigns when the app starts, right after the SDK is initialized, and then resuming where the messages can be shown. Just pause again when the user leaves that "safe" area of your app.
Opening an external webview
The plugin allows you to launch a native web view with a given url
and be able to performs logs from that external resource. In order to do so, if you want to open url https://s3-eu-west-1.amazonaws.com/fa-sdk-files/index.html
in a native web view launched from your html code, call the following method from your PhoneGap HTML:
FollowAnalytics.openWebView(URL, TITLE, CLOSE_BUTTON_TEXT);
<a href="#" onclick="FollowAnalytics.openWebView('https://s3-eu-west-1.amazonaws.com/fa-sdk-files/index.html', 'Test Log', 'Close'); return false;">Open WebView with title</a>
URL
argument will contain the url of the page to display (required), the TITLE
argument will be shown as the title for the NavigationBar (optional, iOS only), and the CLOSE_BUTTON_TEXT
will contain the text for the close button (optional, iOS only, defaults to “close”).
Please check the html at https://s3-eu-west-1.amazonaws.com/fa-sdk-files/index.html
to see how to tag your external pages.
Current available methods are:
logEvent(name, details)
logError(name, details)
setUserId(userId)
unsetUserId()
NOTE: if you're tagging from a link and the link has a real href
set, the sdk will handle that for you, performing the onclick
action and redirecting you right after.
Migration and Troubleshooting
Migration from 4.x
Although previous versions of the FollowAnalytics plugin respected Cordova guidelines of integration they still required developers to perform modifications to the native code for each supported platform.
This new version changes things as it can be used without having to modify nothing but the config.xml
and the html/js
code.
If you plan to update from older versions, the shortest path would be to:
- remove the FollowAnalytics plugin
- remove both platforms (iOS and Android)
- add back the platforms (iOS and Android)
- add back the FollowAnalytics plugin
- follow this installation guide from the top
If you plan to keep the current code you'll need to remove all the code needed to integrate previous plugin versions (please check older plugin documentation to know exactly what to remove).
Troubleshooting
If you eventually run into an error like:
Refused to execute inline event handler because it violates the following Content Security Policy directive: "default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'". Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
Be sure to replace the line
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
on your index.html
by
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'" >
This will enable the logging of events.