An Overview of Mobile Integration with

Olha Prokopiuk

Feb 07, 2019


An Overview of Mobile Integration with


In a previous post, we discussed How to integrate with on the server-side using AmpTokens. In this post, we will discuss basic concepts related to mobile integrations with for iOS and Android. For a quick introduction to the key concepts in that are necessary to follow this post, please see vs A/B Testing: A paradigm shift and How to Implement Autonomous Optimization Projects Using

In many cases, mobile apps provide more responsive, smooth and convenient experience for users. Mobile vs desktop traffic and usage data shows this. Optimizing app experience on the client side with allows both large companies and small teams to react quickly and provide an experience that is personalized for each user group.

Client-side decision-making with mobile integrations is possible and preferred when all of the context needed for decision-making and outcomes are available on the client-side. For more information on differences between client-side and server-side integrations, refer to our Overview of Server-side Integrations with

Detailed instructions for adding the libraries into your application can be found on respective Github projects for iOS and Android.

Example use-case

In the following section we will go over several steps that will showcase an integration of into a real project - Simple Habits Tracker. We had a hypothesis that users who doesn’t have a lot of items in the list may want to go to Ideas tab first and pick up something interesting. However, users who have a lot of items want to go and check in their progress. In other words, new and return users want to see different tabs on application startup.

Let’s create an experiment and try it.

Add library to your project


Insert the following line into Podfile, and run `pod install` to fetch library

pod 'AmpiOS'


Insert the following line into build.gradle and sync to fetch library

compile 'com.github.ScaledInference:amp-android:LATEST_VERSION'

Create amp object

The Amp object is the main component of the mobile Amp API and corresponds to a single project. It manages communication to the server, persists the current user session and makes decisions. It should be created once at app startup and referenced for the lifetime of the application to handle session lifecycle properly. When initialized, Amp represents a single session in the Amp project. How to define a user session is completely up to you. The default behavior is to end the session after a certain inactivity period (the app in background state and no events were fired) or defined time interval since session creation. In this case, the default behavior is desirable, as when a next time the app is open, a new tab may need to be presented.


Create amp in Application#application(_:didFinishLaunchingWithOptions:).

amp = Amp(key: "<your_project_key>")


Create amp in AppDelegate#onCreate()

mAmp = new Amp(this, "<projectKey>");


To make an informed decision, the Amp client should be provided with user context. This can be done by including an observe event with relevant information about the user and application state. The Amp client will then be able to find the best matching decision based on the observed context. Amp captures some basic context by default. However, you may have more relevant and useful information about the current user. For this case, the hypothesis that people behaviour depends on the list size. We need to send these information to amp, and it’s simple to do through amp.observe.


amp.observe(name: "Context",
 properties: ["popular_category": popularCategory,
 "number_of_items" : numberOfItems,
 "number_of_personal_items": numberOfPersonalItems]);


Map<String, Object> properties = new HashMap<>();
properties.put("popular_category", popularCategory);
properties.put("number_of_items", numberOfItems);
properties.put("number_of_personal_items", numberOfPersonalItems);
mAmp.observe("Context", properties);


amp.decide will select the best candidate based on context. The execution is immediate, so it’s safe to call it on the main thread.


let decisions = amp.decide(name: "Select tab", candidates: [optionsKey: ["Ideas", "Doing", "Done"]])
let tab = decisions[optionsKey]


Map<String, List<Object>> candidates = new HashMap<>();
candidates.put(optionsKey, Arrays.<Object>asList("Ideas", "Doing", "Done"));
Map<String, Object> decision = mAmp.decide("Select tab", candidates);
String tab = (String) decision.get(optionsKey);


After making a decision, it’s important to observe the outcome from the user. This may be that they completed a checkout flow because of the decision presented, or that they subscribed to your service. Whatever metric you care most about should be observed if it has occurred.

In this case, when the tab is switched within 5 seconds after the start, it’s evaluated as a negative outcome - the user probably wanted to see a different page.

amp.observe(name: "Tab declined")


mAmp.observe("Tab declined");

In the console, we created the metric to minimize the occurrence of “Tab declined” event:


You could also verify that all events occur in the right order (context, decide, outcome) in the ‘SAMPLE SESSIONS’ section but clicking on the “information” icon in the Sessions section.



After running the experiment couple of weeks, we had the following result.


Here is a learned rule:


It means that users who have less than 4 items in the list would prefer to explore Ideas tab, and users who has more items would prefer to go to Doing tab. is continuously learning, and this could change with time.


In this post we showed how straightforward it is to integrate your mobile application with It included just several clearly defined steps and was integrated within minutes. You can refer to the flow in the sample when integrating into your app. For more information, please contact us here.