| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Aware ESM (com.awareframework.ios.sensor.esm) is a plugin for the AWARE Framework. It loads Experience Sampling Method (ESM) survey schedules from JSON, schedules local notifications, presents survey items through the provided SwiftUI views, and stores answer, dismissal, and expiration events.
iOS 16 or later.
You can integrate this framework into your project via Swift Package Manager (SwiftPM).
Open Package Manager Windows
Find the package using the manager
Import the package into your target.
Import the library into your source code.
import com_awareframework_ios_sensor_esmClass to hold the configuration of the sensor.
| Type | Name | JSON fields |
|---|---|---|
| 1 | Free Text | common fields |
| 2 | Radio | esm_radios |
| 3 | Checkbox | esm_checkboxes |
| 4 | Likert Scale | esm_likert_max, esm_likert_min_label, esm_likert_max_label, esm_likert_step |
| 5 | Quick Answer | esm_quick_answers |
| 6 | Scale | esm_scale_min, esm_scale_max, esm_scale_start, esm_scale_min_label, esm_scale_max_label, esm_scale_step |
| 7 | DateTime | common fields |
| 8 | PAM (Photographic Affect Meter) | common fields |
| 9 | Numeric | common fields |
| 10 | Web | esm_url |
| 11 | Date Picker | common fields |
| 13 | Clock | common fields |
| 14 | Picture | esm_camera |
| 15 | Audio | common fields |
| 16 | Video | esm_camera |
The schedule JSON is an array of schedule objects. Dates use MM-dd-yyyy format.
[
{
"schedule_id": "daily_mood",
"hours": [9, 17],
"start_date": "01-01-2026",
"end_date": "12-31-2050",
"expiration": 30,
"randomize": 10,
"notification_title": "Daily Survey",
"notification_body": "Please answer a few questions",
"interface": 0,
"esms": [
{
"esm": {
"esm_type": 4,
"esm_title": "How are you feeling?",
"esm_instructions": "Choose a number from 1 to 5",
"esm_likert_max": 5,
"esm_likert_max_label": "Great",
"esm_likert_min_label": "Poor",
"esm_likert_step": 1,
"esm_submit": "Submit",
"esm_trigger": "daily_mood_0_likert",
"esm_expiration_threshold": 60,
"esm_na": 0
}
}
]
}
]A complete all-types sample is available at Examples/esm_all_types_sample.json.
| Field | Type | Description |
|---|---|---|
| id | Int64 | Local database primary key |
| deviceId | String | AWARE device UUID |
| timestamp | Int64 | Unix time in milliseconds when the record was created |
| timezone | Int | Raw timezone offset of the device |
| os | String | Operating system of the device |
| jsonVersion | Int | JSON schema version |
| label | String | Customizable data label |
| scheduleId | String | Parent schedule ID |
| esmTrigger | String | ESM trigger identifier |
| esmType | Int | Numeric ESM type |
| esmTitle | String | Question title |
| esmInstructions | String | Question instructions |
| esmAnswer | String | Answer value. Multi-value answers can be JSON encoded |
| esmAnswerTime | Int64 | Unix time in milliseconds when the answer was submitted |
| esmStatus | Int | 0=new, 1=answered, 2=dismissed, 3=expired |
| esmNotificationTime | Int64 | Unix time in milliseconds when the notification fired |
let sensor = ESMSensor(ESMSensor.Config().apply { config in
config.debug = true
config.dbType = .sqlite
config.dbPath = "aware_esm"
config.dbTableName = ESMData.databaseTableName
config.sensorObserver = Observer()
})
sensor.start()
let url = Bundle.main.url(forResource: "esm_schedule", withExtension: "json")!
try sensor.loadSchedules(from: url)class Observer: ESMSensorObserver {
func onScheduleLoaded(schedules: [ESMSchedule]) {
print("Loaded schedules:", schedules.count)
}
func onESMAnswered(data: ESMData) {
print("Answered:", data.esmTrigger, data.esmAnswer)
}
func onESMDismissed(data: ESMData) {
print("Dismissed:", data.esmTrigger)
}
func onESMExpired(data: ESMData) {
print("Expired:", data.esmTrigger)
}
}The package includes SwiftUI views for supported ESM item types and ESMFormView for rendering a full schedule.
ESMFormView(
schedule: schedule,
notificationTime: notificationTime,
onCompleted: { answers in
for (trigger, answer) in answers {
let item = schedule.esms.first { $0.esm.esmTrigger == trigger }?.esm
if let item {
sensor.submitAnswer(
item: item,
scheduleId: schedule.scheduleId,
answer: answer,
notificationTime: notificationTime
)
}
}
},
onDismissed: {
for wrapper in schedule.esms {
sensor.dismissESM(
item: wrapper.esm,
scheduleId: schedule.scheduleId,
notificationTime: notificationTime
)
}
}
)The PAM question type (type 8) presents a 4×4 grid of photographs arranged on the circumplex model of affect (valence × arousal). The user selects the image that best matches their current emotional state.
Images are sourced from the smalldatalab/android-pam repository and are fetched at runtime from:
https://raw.githubusercontent.com/smalldatalab/android-pam/master/app/src/main/assets/pam_images/{id}_{name}/{id}_1.jpg
The 16 affect categories are arranged as follows:
| Unpleasant ← | → Pleasant | ||
|---|---|---|---|
| High Arousal ↑ | Afraid | Tense | Excited |
| Frustrated | Angry | Happy | |
| Miserable | Sad | Calm | |
| Low Arousal ↓ | Gloomy | Tired | Sleepy |
Reference:
Pollak, J. P., Adams, P., & Gay, G. (2011). PAM: a photographic affect meter for frequent, in situ measurement of affect. In Proceedings of the SIGCHI Conference on Human Factors in Computing Systems (CHI '11), pp. 725–734. ACM. https://dl.acm.org/doi/10.1145/1978942.1979047
Yuuki Nishiyama (The University of Tokyo), nishiyama@csis.u-tokyo.ac.jp
Copyright (c) 2025 AWARE Mobile Context Instrumentation Middleware/Framework (http://www.awareframework.com)
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
| Back | FazBrowse Home | New Git URL |