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.
For an example, check out our PhoneGap sample integration code on Github.
For more information, please read the iOS and Android FollowAnalytics SDK documentations.
Install the SDK
-
Download the FollowAnalytics SDK from the developer portal.
-
Use the
cordova
CLI to add the plugin to your app:cordova plugin add /path/to/fa-sdk-phonegap-plugin
Initialize with your API keys
Prepare your API keys
Be sure to have your API keys for this step of the configuration. If you are not sure where to find them, please reach out to your Customer Success Manager or message support@followanalytics.com
iOS
-
In your
AppDelegate.m
, import the SDK header:#import <FollowApps/FAFollowApps.h>
-
In the method
didFinishLaunchingWithOptions
of the same file, add:[FAFollowApps configureWithId:API_KEY_STRING debugStateOn:FADEBUG options:launchOptions];
Android
-
Add Google Play GCM and Google Play Location version 29.0.0 to your project.
-
In your manifest, add the following line :
<application> [...] <meta-data android:name="FAID" android:value="YOUR_API_KEY"/> [...] </application>
-
Update your
Application
class, or create a new one, so that it matches the following example:import android.app.Application; import com.followapps.android.* ; public class MainApplication extends Application { @Override public void onCreate() { super.onCreate(); FollowApps.init(this); FollowApps.registerGcm(); } }
-
If you added a new Application file, don't forget to reference it in your Manifest:
<application ... android:name="MainApplication">
Define the URL scheme
To allow users to retrieve their device ID for campaign testing and tagging plan debugging, you need to define a URL scheme in your iOS and Android projects.
iOS
Declare a URL Scheme in the info tab of your Xcode project using the bundleId of your app as URL Scheme:
Make sure that the bundle ID of your app appears in the URL Schemes field as shown in the screenshot (where com.follow-apps.followme.inHouse
needs to be replaced).
Android
- Edit your AndroidManifest.xml file to add this:
<activity android:name="com.followapps.android.internal.activities.DeviceIdActivity" > <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:host="followanalytics.com" android:path="/deviceId" android:scheme="%YOUR_APP_PACKAGE_NAME%" /> </intent-filter> </activity>
Where %YOUR_APP_PACKAGE_NAME%
should be replaced by the Android package name of your app.
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, or in the native iOS code after the SDK initialization.
HTML
<a href="#" onclick="FAFollowApps.registerForPush()">register for push</a>
Objective-C
[FAFollowApps configureWithId:@"API_KEY_STRING" debugStateOn:FADEBUG options:launchOptions];
[FAFollowApps registerForPush];
Android
Build in release mode
The app must be built on release mode in order to receive push notifications
The FollowAnalytics SDK supports push notifications based on Google Cloud Messaging.
-
Add the following permissions to your manifest:
<permission android:name="%YOUR_APP_PACKAGE_NAME%.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="%YOUR_APP_PACKAGE_NAME%.permission.C2D_MESSAGE" />
-
Add the GCM Receiver to your manifest
<receiver android:name="com.google.android.gms.gcm.GcmReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND" > <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE"/> <!-- for Gingerbread GSF backward compat --> <action android:name="com.google.android.c2dm.intent.REGISTRATION"/> <category android:name="%YOUR_APP_PACKAGE_NAME%"/> </intent-filter> </receiver>
-
In your
Application
subclass, ensure you've added theregisterGCM()
callpublic class MyAwesomeApplication extends Application { [...] @Override public void onCreate() { super.onCreate(); FollowApps.init(this); FollowApps.registerGcm(); [...] } [...] }
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="FAFollowApps.logEvent('My event', 'My event details')">Log an event</a>
<a href="#" onclick="FAFollowApps.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 associated multiple key-values for additional context.
For instance, logging the appearance of a view could be done the following way:
FAFollowApps.logEvent('Product view', Product reference);
FAFollowApps.logEvent('Add product to cart', {'product_id': 'ABCD123',
'product_category': 'Jeans'});
User ID and attributes
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:
FAFollowApps.setUserId("user_id@email.com");
If you want to remove the user identifier (in case of a sign out for instance) use the following method:
FAFollowApps.unsetUserID();
Predefined attributes
The SDK allows to set values for both custom and predefined attributes.
For predefined attributes, the SDK has the following properties:
FAFollowApps.setUserFirstName("Peter");
FAFollowApps.setUserLastName("Jackson");
FAFollowApps.setUserCity("San Francisco");
FAFollowApps.setUserRegion("California");
FAFollowApps.setUserCountry("USA");
FAFollowApps.setUserGender(FollowAnalytics.Gender.Male);
FAFollowApps.setUserEmail("mail@mail.com");
FAFollowApps.setUserBirthDate("2001-02-22");
FAFollowApps.setUserProfilePicture("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:
FAFollowApps.setNumberAttribute('key', "1");
FAFollowApps.setStringAttribute('key', "A custom string attribute");
FAFollowApps.setBooleanAttribute('key', "true");
FAFollowApps.setDateAttribute('key', "2016-10-26");
FAFollowApps.setDateTimeAttribute('key', "2016-10-26T11:22:33+01:00");
For example, to set the user's job:
FAFollowApps.setStringAttribute("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:
FollowApps.deleteUserAttribute("job");
Set of Attributes
You can add or remove an item to or from a set of attributes.
To add an item:
FAFollowApps.addToUserAttributeSet("fruits", "apple");
FAFollowApps.addToUserAttributeSet("fruits", "banana");
To remove an item:
FAFollowApps.removeFromUserAttributeSet("fruits", "apple");
And to clear a set:
FAFollowApps.emptyUserAttributeSet("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.
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 retreive 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 deeplinking 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 FollowApps.init(this)
line:
FollowApps.setMessageHandler(new MyAwesomePushMessageHandler());
Android: Handle deeplinking from javascript
To handle the deeplinking from your javascript code, have this run when the device is ready:
onDeviceReady: function() {
...
window.FAFollowApps = cordova.require("com/cordova/followapps/plugin");
FAFollowApps.handleDeeplink();
FAFollowApps.on("onPushMessageClicked",function(data){
console.log(JSON.stringify(data));
});
FAFollowApps.on("onPushDeeplinkingClicked",function(data){
console.log(JSON.stringify(data));
});
FAFollowApps.on("onInAppMessageClicked",function(data){
console.log(JSON.stringify(data));
});
....
},
As you can notice here, the plugin provides the following events : onPushMessageClicked
, onPushDeeplinkingClicked
and onInAppMessageClicked
.
-
PushMessageClicked: When the user click on the push, you can retrieve all the added parameter as following:
FAFollowApps.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 click on the push, you can retrieve the url as follows:
FAFollowApps.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:
FAFollowApps.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>
Where %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:
FAFollowApps.pauseCampaignDisplay();
FAFollowapps.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:
FAFollowApps.openWebView(URL, TITLE, CLOSE_BUTTON_TEXT);
Somethign like:
<a href="#" onclick="FAFollowApps.openWebView('https://s3-eu-west-1.amazonaws.com/fa-sdk-files/index.html', 'Test Log', 'Close'); return false;">Open WebView with title</a>
The 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 to 4.1.0
Since version 4.1.0, the FollowAnalytics plugin is updated to respect cordova plugin standard.
So to call a method, you have to init FAFollowApps instance and call the method on it. However, you can always continue to use the deprecated methods.
All methods have been renamed. For example :
FALogEvent('My event', 'My event details')
became
FAFollowApps.logEvent('My event', 'My event details')
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. 0