Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import platform.HealthKit.HKObjectType
import platform.HealthKit.HKQuantityType
import platform.HealthKit.HKQuantityTypeIdentifier
import platform.HealthKit.HKQuantityTypeIdentifierActiveEnergyBurned
import platform.HealthKit.HKQuantityTypeIdentifierBasalEnergyBurned
import platform.HealthKit.HKQuantityTypeIdentifierBodyMass
import platform.HealthKit.HKQuantityTypeIdentifierHeartRateVariabilitySDNN
import platform.HealthKit.HKQuantityTypeIdentifierStepCount
Expand Down Expand Up @@ -55,7 +56,7 @@ actual class HealthDataReader {
suspend fun requestPermissionsIos(permissions: Set<TanayenPermission>): Boolean {
if (!HKHealthStore.isHealthDataAvailable()) return false

val readTypes = permissions.mapNotNull { it.toHKType() }.toSet()
val readTypes = permissions.flatMap { it.toHKTypes() }.toSet()

return suspendCancellableCoroutine { cont ->
store.requestAuthorizationToShareTypes(
Expand Down Expand Up @@ -86,7 +87,16 @@ actual class HealthDataReader {
startDate,
endDate,
)?.let { it * 1000f }
val calories = readCalories(startDate, endDate)?.toInt()
// Total quemado = activas + basal (HealthKit no tiene un tipo "total" único como
// Health Connect; hay que sumar los dos). Coincide con "Calorías quemadas" de Android.
val activeKcal = readEnergy(HKQuantityTypeIdentifierActiveEnergyBurned, startDate, endDate)
val basalKcal = readEnergy(HKQuantityTypeIdentifierBasalEnergyBurned, startDate, endDate)
val calories =
if (activeKcal == null && basalKcal == null) {
null
} else {
((activeKcal ?: 0.0) + (basalKcal ?: 0.0)).toInt()
}
val weight =
readQuantity(
HKQuantityTypeIdentifierBodyMass,
Expand Down Expand Up @@ -217,16 +227,16 @@ actual class HealthDataReader {
store.executeQuery(query)
}

// TODO(iOS): el card se llama "Calorías quemadas" (total). Aquí solo se lee la energía
// ACTIVA (HKActiveEnergyBurned); falta sumar la basal (HKBasalEnergyBurned) y pedir su
// permiso para que coincida con el total. Pendiente para cuando iOS se distribuya.
private suspend fun readCalories(
// Suma acumulada de un tipo de energía (activa o basal) en el rango. Reutilizable para
// componer el total quemado.
private suspend fun readEnergy(
identifier: HKQuantityTypeIdentifier,
start: NSDate,
end: NSDate,
): Double? =
suspendCancellableCoroutine { cont ->
val caloriesType =
HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierActiveEnergyBurned)
HKQuantityType.quantityTypeForIdentifier(identifier)
?: return@suspendCancellableCoroutine cont.resume(null)
val predicate = HKSampleQuery.predicateForSamplesWithStartDate(start, end, 0u)
val query =
Expand All @@ -247,30 +257,30 @@ actual class HealthDataReader {

// ── Helpers ───────────────────────────────────────────────────────────────

private fun TanayenPermission.toHKType(): HKObjectType? =
// Un permiso puede mapear a varios tipos de HealthKit (calorías = activa + basal).
private fun TanayenPermission.toHKTypes(): Set<HKObjectType> =
when (this) {
TanayenPermission.SLEEP -> {
HKCategoryType.categoryTypeForIdentifier(HKCategoryTypeIdentifierSleepAnalysis)
setOfNotNull(HKCategoryType.categoryTypeForIdentifier(HKCategoryTypeIdentifierSleepAnalysis))
}

TanayenPermission.HEART_RATE_VARIABILITY -> {
HKQuantityType.quantityTypeForIdentifier(
HKQuantityTypeIdentifierHeartRateVariabilitySDNN,
)
setOfNotNull(HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRateVariabilitySDNN))
}

TanayenPermission.CALORIES_BURNED -> {
HKQuantityType.quantityTypeForIdentifier(
HKQuantityTypeIdentifierActiveEnergyBurned,
setOfNotNull(
HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierActiveEnergyBurned),
HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBasalEnergyBurned),
)
}

TanayenPermission.WEIGHT -> {
HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMass)
setOfNotNull(HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMass))
}

TanayenPermission.STEPS -> {
HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount)
setOfNotNull(HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount))
}
}

Expand Down
Loading