App Setup: Instrumenting variables - [Sample: iOS, Android]

In this tutorial we are going to see how to instrument variables that can take on new values from the server. This allows to roll out changes without having to push an update through the store. A/B tests can also be created to change variables for only a percentage of your users.

The procedure for handling Leanplum variables runs through those steps:

  1. Define the Variables in your project. Variables can be of different kind - int, booleans, Strings, Dictionaries, Files - and depending on the specific platform can be defined in different ways. See specific platforms sections below.

  2. Run the app in Development mode and Register the Device in the Test Device Dashboard area. 
    In this way, the Variables defined on the client are being synced with the Dashboard.

    For example: 


  3. Access to variables values in your code callbacks. Variable data comes back asynchronously when the app starts. When using Variables values, you should wait to use your variables and resources until they are retrieved from the server. See specific platforms sections below.

 

iOS

Sample: full project here

Defining Variables

On iOS with ObjC, you can define variables in any class of your code, outside of your methods, like you would a constant.

Using the DEFINE_VAR macros allows to grab all the Variables values as soon as the project is started.

In this sample we are defining Variables both in the AppDelegate.m and in ViewController.m using the DEFINE_VAR macros to define different kind of variables (in this case String, boolean, float, int as well as a dictionary and a file).

For example, in AppDelegate.m:

DEFINE_VAR_STRING(welcomeMessage, @"Welcome to Leanplum!");
DEFINE_VAR_BOOL(showAds, false);
DEFINE_VAR_FLOAT(floatvar, 1.5);
DEFINE_VAR_INT(intvalue, 20);

DEFINE_VAR_DICTIONARY_WITH_OBJECTS_AND_KEYS(
                                            powerup,
                                            @"Turbo Boost", @"name",
                                            @150, @"price",
                                            @1.5, @"speedMultiplier",
                                            @15, @"timeout",
                                            nil);

 

or in another class like ViewController.m:

DEFINE_VAR_FILE(LPsquarelogo, @"leanplum-squarelogo.png");

When the project is launched in Development mode and the device is registered, all the Variables defined using the DEFINE_VAR macros all over the project will be synced and added to the Dashboard. 

Using Callbacks

When the app starts, Variable data comes back asynchronously- therefore you should use Variables values from inside Leanplum Callbacks to make sure the updated values are always used.

Following the sample project code, once the app starts, callbacks are triggered based on when variables vales are changed and in our case their values are print in console log:

[Leanplum onVariablesChanged:^{
        NSLog(@"%@", welcomeMessage.stringValue);
        NSLog(@" %s", showAds.boolValue ? "true" : "false");
        NSLog(@"%0.1f", floatvar.floatValue);
        NSLog(@"%d", intvalue.intValue);
        NSLog(@"%2f", [[powerup objectForKey:@"speedMultiplier"] floatValue]);
    }];

In case of files, the callback is slightly different and is triggered when the file is also for sure downloaded from the server.

For example, in the ViewController.m class, we are setting the image only when also there are no downloads pending and the image is received for sure:

[Leanplum onVariablesChangedAndNoDownloadsPending:^{
        LPlogo.image = LPsquarelogo.imageValue;
    }];

 See the Sample project for more details. 

Android

Sample: full android variables project here.

Defining Variables

In an Android project, Variables can be defined in a few different ways. 

a) Using @Variable annotation

You can define these variables outside of the onCreate() method:

  • Inside your Application class that extends LeanplumApplication.
  • In your main activity that extends one of the LeanplumActivity classes and calls Leanplum.start
  • In another class. Use the Parser class to detect the annotations before calling Leanplum.start

b) Using Var.define

  • Anywhere in your Class before starting Leanplum. 
  • In another class outside of the onCreate() method. Use also in this case the Parser class to detect the variable before calling Leanplum.Start

 In this sample, we are defining different variables in different Activities and in the Application class as well. 

When the App starts, the code in the Application class is being executed, as well as the in the MainActivity. The Variables defined in the other classes are being Parsed inside the onCreate() method before Leanplum start.

In the sample, we are starting Leanplum in the Application class, which is also not extending a LeanplumApplication class but we are implementing the Session Lifecycle manually.

For example:

@Override
    public void onCreate() {
        super.onCreate();
        Leanplum.setApplicationContext(this);
        Parser.parseVariables(this);
        Parser.parseVariablesForClasses(AnotherActivity.class, AnotherLPactivity.class);
        LeanplumActivityHelper.enableLifecycleCallbacks(this);

 

Other variables are defined in the Application class itself before Leanplum start. See the sample project linked above - check all the Activities.class as an example.

Using Callbacks

Once the Variables are synced, they are used inside callbacks in order to be sure their values are updated. You can place callbacks where you need to use those Variables values.

In the project sample code, we are printing out the values of Variables defined in the Application class directly from there or also from another activity. 

So, for example, in the Application class:

Leanplum.addVariablesChangedHandler(new VariablesChangedCallback() {
@Override
public void variablesChanged() {

Log.i("#### ", welcomeLabel.value());

for (Map.Entry<String, Object> entry : powerup.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
Log.i("#### ", "Application class var : " + key + " " + value.toString());
}
}
});

In the MainActivity class (accessing to variables defined in the Application class):

Leanplum.addVariablesChangedHandler(new VariablesChangedCallback() {
@Override
public void variablesChanged() {
welcomeMessageText1.setText(ApplicationClass.String_Welcome1);
welcomeMessageText2.setText(ApplicationClass.String_Welcome2);
}
});

Also, for images, we have to make sure that the image value is being used after it has been downloaded, so in that case "Leanplum.addVariablesChangedAndNoDownloadsPendingHandler" can be used. 

See the sample project for more details. 


Was this article helpful?
Have more questions? Submit a request