MeData Service
MeData Service is the core of the Mobile SDK. It collects MeData values from various sources according to the MeData Definitions managed on Orchestrator. Most of other Mobile SDK services are triggered or effected by MeData Service.
Mobile SDK performs background network access to fetch MeData Definitions from DataSapien Orchestrator.
Data Vault
MeData collected by Mobile SDK is always stored on user device. Data is stored in a platform encrypted and sandboxed data base that is called the Data Vault. MeData Service provides methods to query and consume stored MeData in Data Vault.
MeData Collection
Mobile SDK collects data from various sources:
Native— MeData Service executes the native code it contains to access mobile device & OS related data. All native MeData are automatically refreshed to their latest values duringDataSapien.setup.Script— MeData Service executes the script authored on Orchestrator during MeData Definition creation.Question— self reported data in the form of question answers. Mobile SDK provides its own WebView based UI for answering questions — the same rendering used by Journeys. MeData collected inside a Journey is automatically saved to the Data Vault.Inferred / Provided— computed MeData: existing data is turned into new data on device. The value is calculated by a Script or a Rule and written to the Data Vault withsaveMeDataRecord. For examplelocationis a MeData collected from the user; a script or rule derives thecityfrom it and saves it — from that point oncitybehaves like any other MeData and can be used in Audience targeting.
MeData is what powers the rest of the platform: Audiences are built on MeData values for targeting, and the data a Journey requests as ZPD comes from MeData. The richer the Data Vault, the better the targeting and personalization.
MeData Model
Every MeData has two sides:
MeDataDefinition— the definition, authored on the Orchestrator: programmatic name, data type, constraints, category and storage settings.MeData— the user-side data of that definition, stored longitudinally in the Data Vault.
The data itself is hierarchical: MeData → MeDataRecord → MeDataValue. MeData holds everything recorded for a definition over time; each MeDataRecord is one entry; each MeDataValue is one value inside that entry.
For example, a multiple-choice favorite_color MeData where the user can pick more than one answer:
MeData → [red, blue], [white], [red] // all entries over time
MeDataRecord → [red, blue] // one entry
MeDataValue → red // one value in the entry
Use Cases
All of the functions below are also available to Scripts, so Journeys and Rules can query and write MeData the same way your host app does.
Working with Definitions
MeData Definitions are synchronized during DataSapien.setup; call DataSapien.syncAll to synchronize explicitly at any other time.
getMeDataDefinitionsreturns all definitions on the device.getMeDataDefinition(name)returns a single definition by its programmatic name — the name defined on the Orchestrator.getMeDataCategoriesreturns all categories, andgetMeDataDefinitionsByCategory(name)the definitions in one category.
Saving Data into the Vault
saveMeDataRecord(name, values) writes a new record for the given definition. values is intentionally loosely typed because a MeData can have different shapes and types:
- The value must match the definition's data type (
STRING,NUMBER,BOOLEAN,DATETIME,LOCATION, ...). If the type does not match — for example the MeData is aNUMBERbut a string is sent — the call fails with an error. - If the definition is
multivalued, an array of values is expected; otherwise a single value is expected and passing an array fails.
How records accumulate is controlled by the definition's storage settings on the Orchestrator:
- Store Value Count — MeData is longitudinal: new records are appended over time. This setting caps how many records are kept (default 100). When the cap is exceeded, the oldest record is deleted and the new one is added.
- Store Only If Value Changes — when enabled, the new value is compared with the latest record and saved only if it changed.
A typical data onboarding scenario — your host app already knows something about the user and wants it in the Data Vault so Audiences and Journeys can use it. For example, recording the user's profession: create a MeData on the Orchestrator with type STRING and single value, then:
DataSapien.getMeDataService().saveMeDataRecord(
name: "profession",
values: "computer engineer",
onSuccess: {
},
onError: { error in
}
)
Reading from the Vault
getMeDataRecords(name)returns all records of a MeData.getLastMeDataRecord(name)returns the most recent record.
Aggregating Numeric MeData
Because MeData is longitudinal, a numeric MeData such as step_count is a series of records rather than a single value. Aggregation turns that series into the numbers a screen or a Journey actually needs — the total of the last week, the daily average, the best day — without reading every record and reducing it yourself. Aggregation is only available for definitions whose data type is NUMBER.
Two functions cover the two shapes of the question. getAggregatedMeDataRecord answers with one number for the whole range, and getAggregatedMeDataRecordIntervals answers with one number per window — the shape a chart needs. Both take the range as epoch milliseconds and support SUM, MIN, MAX and AVG.
An empty range never comes back as 0. The value is null instead, so "nothing was collected" stays distinguishable from a measured zero — the same distinction matters per window, where a day with no data carries null while every other day carries its total.
The total of the last seven days:
DataSapien.getMeDataService().getAggregatedMeDataRecord(
name: "step_count",
startDate: startDate,
endDate: endDate,
aggregation: .sum,
onSuccess: { record in
// record.value is nil when nothing was collected in the range
},
onError: { error in
}
)
aggregationInterval adds a second stage: records are first reduced per window, then the outer aggregation runs over those window results. That is what separates the average daily step count from the average of individual step records — sum each day, then average the days:
DataSapien.getMeDataService().getAggregatedMeDataRecord(
name: "step_count",
startDate: startDate,
endDate: endDate,
aggregation: .avg,
aggregationInterval: AggregationInterval(seconds: 86400, aggregation: .sum),
onSuccess: { record in
},
onError: { error in
}
)
When the windows themselves are the answer, ask for the intervals. Every window in the range is returned, in ascending order, so the result maps directly onto a chart's axis:
DataSapien.getMeDataService().getAggregatedMeDataRecordIntervals(
name: "step_count",
startDate: startDate,
endDate: endDate,
aggregationInterval: AggregationInterval(seconds: 86400, aggregation: .sum),
onSuccess: { records in
// one record per day; value is nil for days without data
},
onError: { error in
}
)
MeData Service Functions
To access MeDataService functions, get its instance from the DataSapien object: DataSapien.getMeDataService().
See the full function list per platform in the MeData Service API Reference.