Data Integration

Sensors

Since Sahha requires device data (such as steps, sleep and other data) in order to analyse health, we need to access the devices sensors. This guide will show you how to configure, and manage device sensors and the data they collect.

The Sahha SDK handles device sensors for your app and acts as a bridge between your app and the device sensors. This simplifies the process of collecting and analyzing device data.


Sensor Settings

You can specify which sensors for the Sahha SDK to use. We suggest asking the user for permission for access to only the sensors that your app needs. This will lower the chance that the user will reject your permission request.

Choose if you want to request permission for all, some, or no sensors.

If you leave the Sensor Settings value to the default value of null, ALL AVAILABLE SENSORS will be requested.

If you set the Sensor Settings value to an array of some specific sensors, ONLY THOSE SENSORS will be requested.

If you set the Sensor Settings value to an empty array [], you will receive an ERROR.

Some sensors are not available on all platforms.

SahhaSensor Android Sensor iOS Sensor
gender Sensor Not Available biologicalSex
date_of_birth Sensor Not Available dateOfBirth
sleep SleepSessionRecord sleepAnalysis
step_count StepsRecord stepCount
floor_count FloorsClimbedRecord flightsClimbed
heart_rate HeartRateRecord heartRate
resting_heart_rate RestingHeartRateRecord restingHeartRate
walking_heart_rate_average Sensor Not Available walkingHeartRateAverage
heart_rate_variability_rmssd HeartRateVariabilityRmssdRecord Sensor Not Available
heart_rate_variability_sdnn Sensor Not Available heartRateVariabilitySDNN
blood_pressure_systolic BloodPressureRecord bloodPressureSystolic
blood_pressure_diastolic BloodPressureRecord bloodPressureDiastolic
blood_glucose BloodGlucoseRecord bloodGlucose
vo2_max Vo2MaxRecord vo2Max
oxygen_saturation OxygenSaturationRecord oxygenSaturation
respiratory_rate RespiratoryRateRecord respiratoryRate
active_energy_burned ActiveCaloriesBurnedRecord activeEnergyBurned
basal_energy_burned Sensor Not Available basalEnergyBurned
total_energy_burned TotalCaloriesBurnedRecord Sensor Not Available
basal_metabolic_rate BasalMetabolicRateRecord Sensor Not Available
time_in_daylight Sensor Not Available timeInDaylight
body_temperature BodyTemperatureRecord bodyTemperature
basal_body_temperature BasalBodyTemperatureRecord basalBodyTemperature
sleeping_wrist_temperature Sensor Not Available appleSleepingWristTemperature
height HeightRecord height
weight WeightRecord bodyMass
lean_body_mass LeanBodyMassRecord leanBodyMass
body_mass_index Sensor Not Available bodyMassIndex
body_fat BodyFatRecord bodyFatPercentage
body_water_mass BodyWaterMassRecord Sensor Not Available
bone_mass BoneMassRecord Sensor Not Available
waist_circumference Sensor Not Available waistCircumference
stand_time Sensor Not Available appleStandTime
move_time Sensor Not Available appleMoveTime
exercise_time Sensor Not Available appleExerciseTime
activity_summary Sensor Not Available activitySummary
device_lock devicelock Sensor Not Available
exercise ExerciseSessionRecord workout

public enum SahhaSensor: String, CaseIterable {
case gender
case date_of_birth
case sleep
case step_count
case floor_count
case heart_rate
case resting_heart_rate
case walking_heart_rate_average
case heart_rate_variability_sdnn
case heart_rate_variability_rmssd
case blood_pressure_systolic
case blood_pressure_diastolic
case blood_glucose
case vo2_max
case oxygen_saturation
case respiratory_rate
case active_energy_burned
case basal_energy_burned
case total_energy_burned
case basal_metabolic_rate
case time_in_daylight
case body_temperature
case basal_body_temperature
case sleeping_wrist_temperature
case height
case weight
case lean_body_mass
case body_mass_index
case body_fat
case body_water_mass
case bone_mass
case waist_circumference
case stand_time
case move_time
case exercise_time
case activity_summary
case device_lock
case exercise
}

(Android) Uses Permission - IMPORTANT INFO

Specifying Sensors for Android

For every sensor you specify in getSensorStatus or enableSensors, you will need to include matching uses-permission values in your AndroidManifest.xml.

View the SDK Integration guide for Android .

If the values do not match, you are likely to receive build errors and risk your app being rejected on the Google Play Store!


About the device sensor status

The sensors have multiple possible statuses which indicate whether they are enabled or disabled or anywhere in between.

public enum SensorStatus: Int {
case pending = 0 // Sensors pending (before prompting user for permission)
case unavailable = 1 // Sensors not supported by user's device
case disabled = 2 // Sensors disabled (after prompting user for permission)
case enabled = 3 // Sensors enabled (after prompting user for permission)
}

(iOS) Permission Privacy - IMPORTANT INFO

Apple limits the ability to detect the true sensor status to protect user privacy.

Apple documentation:

To help protect the user’s privacy, your app doesn’t know whether the user granted or denied permission to read data from HealthKit. If the user denied permission, attempts to query data from HealthKit return only samples that your app successfully saved to the HealthKit store.

This means that if a Sensor is available, the only possible SensorStatus is:

  • pending if you have not already prompted the user for permission yet
  • enabled if you have already prompted the user for permission

The disabled SensorStatus is not triggered even if the user declines permission.

The disabled SensorStatus is only included in the iOS SDK to keep parity with the Android SDK.

Please read the official Apple documentation to better understand authorizing access to health data for iOS.

Authorizing access to health data for iOS


Getting the device sensor status

You can check the current status of the sensors by calling getSensorStatus. This method is asynchronous and will return the updated SahhaSensorStatus in its callback.

Configure the SDK before you Get Sensor Status

On app launch, SensorStatus will always be pending. You must configure the SDK before you can get the correct SensorStatus.

We suggest calling getSensorStatus in the callback of configure.

// Get status of `step_count` and `sleep` sensors
Sahha.getSensorStatus([SahhaSensor.step_count, SahhaSensor.sleep])
{ error, sensorStatus in
if let error = error {
print(error)
}
else if sensorStatus == .pending {
// Sensors are NOT enabled and ready - Show your custom UI before asking for user permission
}
else if sensorStatus == .enabled {
// Sensors are enabled and ready
} else {
// Sensors are disabled or unavailable
}
}

Enabling device sensors

Before the SDK can start collecting data, you will need to enable sensors by calling enableSensors. This method is asynchronous and will return the updated SahhaSensorStatus in its callback.

// Enable `step_count` and `sleep` sensors
Sahha.enableSensors([SahhaSensor.step_count, SahhaSensor.sleep])
{ error, sensorStatus in
if let error = error {
print(error)
}
else if sensorStatus == .enabled {
// Sensors are enabled and ready
} else {
// Sensors are disabled or unavailable
}
}

(iOS) Sleep Sensor - IMPORTANT INFO

Setup Sleep Before Using the SDK

In order for the Sahha SDK to collect data from the sleep sensor, Sleep functionality must be enabled by your mobile user BEFORE calling enableSensors.

We suggest checking if your user has seen the HealthKit permission screen before enabling the sleep sensor. If the status is pending, this is the perfect time to show your custom UI asking your user to setup Sleep in the Health App.

Please read the official Apple documentation to help your users setup Sleep for iOS.

Sleep for iOS


Open App Settings

It's possible for your app user to disable a sensor. In this case, you must send the user to the app settings to manually enable the sensor.

Sahha.openAppSettings()

(iOS) Permission Changes - IMPORTANT INFO

App will terminate if Permission Changes

If the user enables / disables a sensor permission from the device settings menu while your app is in the background, the iOS system will force your app to terminate. This is intentional behavior and your app will need to be relaunched.