NAV
iOS Android Unity

Moments SDK

Moments SDK Version 0.7.0

Minimum System Requirements

  • Unity 5.0
  • iOS 8
  • Android 4.4 KitKat (19)

The SDK provides the below features.

Getting started

You will need an API key to start collecting data. You can quickly get one by signing up on our developer portal.

Moments SDK is currently available for 3 platforms. Each platform has its own special installation procedure that you will need to follow.

- (BOOL)application: (UIApplication *)application
    didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {

  [Moments startWithAuthorizationRequest:true
                         runInBackground:true
                              withAPIKey:@"replace-me"];

  return YES;
}
public class HomeActivity extends Activity{

  private Moments momentsClient;
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //...
    momentsClient = MomentsClient.getInstance(this);
  }

  protected void onDestroy() {
    momentsClient.disconnect();
    super.onDestroy();
  }
}
  // Adding prefab to the scene did all the initialization magic
  // You can get access to the client this way
  momentsManager = GameObject.Find("Moments").GetComponent<Moments>();

To get started with basic building of location profile you just need to initialize LotaData Moments SDK and we’ll do the rest. See your specific platform example, or installation instructions.

Depending on your use cases you could stop here. To get even more insights you’d want to tag a few important in-app events.

Often you want to do something special in your app based on location or context. If that is the case, then please read on!

In-App Tags

To tag an in-app event

    [Moments recordEventWithTag:@"launched"];
    // or
    [Moments recordEventWithTag:@"purchase" value:@(2.99)];
    [Moments recordEventWithTags:(NSArray<NSString*> *)tags
                           value: @(2.99)];
    momentsClient.recordEvent("launched");
    // or
    momentsClient.recordEvent("purchase", 2.99);
    momentsClient.recordEvent(Collection<String> tags, 2.99);
    momentsManager.RecordEvent("browsePackages");
    // or
    momentsManager.RecordEvent("purchase", 2.99);

To tag an in-app event, you can call corresponsing record function passing in at least one string and then optional double value.

It is that simple!

Operation Modes

There are different levels we have preconfigured for how location data will get collected. The higher the level the more power will be consumed and the higher the frequency of the location updates that get generated.

By default, Moments SDK starts in TrackingMode.StayDetection mode which works great for understanding behavior patterns, optimizing notification delivery, and being gentle on the battery.

  Moments.trackingMode = kLDTrackingModeRoute;
  momentsClient.setTrackingMode(TrackingMode.Route);
  momentsManager.trackingMode = Moments.TrackingMode.Route;

Changes to the tracking mode will presist between applicaiton launches.

Under the hood we use various algorithms to optimize usage of core services and sensors to dettect important chanages in device state and turn on and off relevant location hardware.

Mode Description
Manual Select Manual mode if you wish to only gather manually triggered location data. This mode will be automatically selected if background processing is disabled or not granted
MinimalPower MinimalPower mode is designed to have close to ZERO BATTERY IMPACT, at the cost of location granularity and confidence which might suffer inside structures, buildings, shopping malls and plazas. This mode provides Plaza level granularity.
StayDetection DEFAULT (<3% BATTERY IMPACT / 24hrs) StayDetection mode captures the precise locations/POIs visited with negligible impact to the battery life. Registers arivals and departures.
Route (4-8% / 24Hr or ~1%/active travel hr) NOTE: Depending on device mobility this may have more or less battery impact. Route mode captures the precise locations visited between each departure and arrival along with a coarse trail, with minimal impact to battery life.
HawkEye (1-2%/hr) NOTE: This mode is best to toggle on for short periods of time. Tracking mode HawkEye captures the complete travel path with super-fine resolution and sufficient granularity for tracking and recording the exact trail, with the detected businesses, places, venues and POIs along the device’s travel path.

Defaults

When you request location or a Stay action is triggered we attempt to get location precission of 12 meters.

We’ll spend up to 60 seconds attempting to get a good location, If the accuracy the device reports is 12 meters or less we will return it immediately so responses can be quick if your in an area with good signal.

Route tracking will attempt to provide location updates every 150 meters, or every 5 minutes.

HawkEye tracking will attempt to provide location updates every 26 meters, or every minute.

These defaults are only suggestions to power management algorithms and actual collected data will differ.

Location Updates

[Moments locationCallback:^(LocationPayload * location) {
  //Example of how you might process the data
  //[[Storage store] saveLocation:location.location withAction:location.action];
}];


@interface LocationPayload : NSObject
  @property (nonatomic, strong) CLLocation * location;
  @property (nonatomic, strong) NSString * action;
  @property (nonatomic, strong) NSArray<NSString*> * tags;
  @property (nonatomic, strong) NSNumber * floor;
  @property (nonatomic, strong) NSDate * arrivalTime;
@end
momentsClient.monitorLocation("anything", new LocationCallback<String>() {
    @Override
    public void handleLocation(String extra, Location loc) {
        Bundle bundle = loc.getExtras();
        String action = bundle.getString(Moments.KEY_TRAIL_ACTION);
        if(Moments.TRAIL_ACTION_DEPARTURE.equals(action)){
          bundle.getLong(Moments.KEY_ARRIVAL_TIME);
        }
        // Do something
    }
});
// Subscribe to `Moments.momentsLocationDelegate` delegate to
//  get notified whenever there is a state change. Your 
//  delegate will be called with `LoactionPayload` structure
//  containing the data.

momentsManager = GameObject.Find("Moments").GetComponent<Moments>();
momentsManager.momentsLocationDelegate += MomentsUpdate;

// For your Reference
public struct LocationPayload
{
    public double latitude;
    public double longitude;
    public double altitude;
    public double horizontalAccuracy;
    public double verticalAccuracy;
    public double course;
    public double speed;
    public long time;
    public long floor;
    public string action;

    //...
    public bool isXSet(){}
}

As soon as the SDK is initialized we’ll get a location fix and begin saving position history locally on the device as well as to the cloud. There is no need for you to persist anything youself.

Moments SDK will provide you with real-time callbacks when device departs, arrives in an area, or we have a confirmed stay. You can also get callbacks when device moves a significant distance depending on your TrackingMode, or a long period of time elapses at the same location.

Along with the location you also get an Action string indicating what type of update that is.

action Description
arrival gets generated when the user arrives at a location
stay happens when LotaData SDK confirms user is staying at a specific location
departure happens when the user leaves a location
move triggered when user moves a significant distance, when in route monitoring mode
ping periodically we will ping the user’s location so we can help you get better insights into where your users are located
sys generated by the SDK to monitor init & transition events
tag generated by you, the user of our SDK

In case of a departure action you may wish to also read corresponding arrivalTime from the payload/bundle.

Current Location

[Moments requestLocation:^(CLLocation * location) {
  //Example of how you might process the data
  //[content localSearch:location];
}];

// Note: Not immediately available on first run
LocationPayload bestKnownLocation = [Moments readHistoricalLocation:0];
momentsClient.requestLocation("anything", new LocationCallback<String>() {
    @Override
    public void handleLocation(String extra, Location loc) {
        // Do something
    }
});

//Note: May return null
momentsClient.getBestKnownLocation();
// Subscribe to `Moments.momentsLocationDelegate` delegate to
//  get notified of all location updates

momentsManager = GameObject.Find("Moments").GetComponent<Moments>();
momentsManager.momentsLocationDelegate += MomentsUpdate;
...
// somewhere else, request a position fix
momentsManager.RequestLocation()

// Note: Not immediately available on first run
momentsManager.bestKnownLocation

You can request a new location fix at any time with a requestLocation call. That will guarantee that supplied location is no older than 60 sec(default).

If under Unity, calls to requestLocaiton would also be delivered to the main registered callback.

Delivered Location object will always have latitude, longitude, and time set, but other fields you should check with isSet function.

If you do not need up to the minute freshness of location, you can also get bestKnownLocation. It may not be set on first application run, but then we guarantee instant efficient access to best known location.

Historical Data

  if(Moments.historySize>0){
    LocationPayload loc = [Moments readHistoricalPosition:0];

    //[yourThing processLocation:loc.location withAction:loc.action withTag:(loc.tags!=nil && loc.tags.count>0 ? loc.tags[0] : nil)];
    }];
  }
  if(momentsClient.getHistorySize()>0){
    loc = momentsClient.getHistoricalPosition(0);
    yourThing.processLocation(loc);
  }
  public void OnApplicationFocus(bool focusStatus) 
  {
    if (focusStatus) {
      numLocationPings = momentsManager.HistorySize();

      // Loop as needed
      location = momentsManager.GetHistoricalPosition(0);
    }
  }

We want to make historial data as easy for you to consume as possible. There are 3 ways of doing it.

To check for new location data when your app relaunches you can check historySize and then call getHistoricalPosition(int).

Location history is a bounded LIFO queue limited to 1000(default) entries. Meaning record 0 is the most recent and record 999 is the oldest.