Introducing AI Conversations: Natural Language Interaction for Your Apps! Learn More
Reading Data
You can query health data from Apple HealthKit and Android Health Connect using the IHealthService interface. Always request read permissions first.
Querying Health Data
Section titled “Querying Health Data”public class HealthDashboardViewModel(IHealthService health){ async Task LoadDataAsync() { // 1. Request permissions (read-only shorthand) var result = await health.RequestPermissions( DataType.StepCount, DataType.HeartRate, DataType.Calories, DataType.Distance );
// Or request per-metric read/write permissions in a single call // await health.RequestPermissions( // (PermissionType.Read, DataType.StepCount), // (PermissionType.Read, DataType.HeartRate), // (PermissionType.Write, DataType.Weight), // (PermissionType.ReadWrite, DataType.BloodPressure) // );
// 2. Check which permissions were granted foreach (var (type, success) in result) { if (!success) Console.WriteLine($"Permission denied for {type}"); }
// 3. Query data for the last 24 hours var end = DateTimeOffset.Now; var start = end.AddDays(-1);
var steps = (await health.GetStepCounts(start, end, Interval.Days)).Sum(x => x.Value); var calories = (await health.GetCalories(start, end, Interval.Days)).Sum(x => x.Value); var distance = (await health.GetDistances(start, end, Interval.Days)).Sum(x => x.Value); var heartRate = (await health.GetAverageHeartRate(start, end, Interval.Days)).Average(x => x.Value);
// 4. Blood pressure returns a special result type var bp = await health.GetBloodPressure(start, end, Interval.Days); if (bp.Any()) { var avgSystolic = bp.Average(x => x.Systolic); var avgDiastolic = bp.Average(x => x.Diastolic); }
// 5. Hourly breakdown var hourlySteps = await health.GetStepCounts(start, end, Interval.Hours); foreach (var bucket in hourlySteps) { Console.WriteLine($"{bucket.Start:g} - {bucket.End:g}: {bucket.Value:N0} steps"); } }}Real-Time Observation
Section titled “Real-Time Observation”See the dedicated Observing Data page for streaming health data changes via IAsyncEnumerable<HealthResult>.
Best Practices
Section titled “Best Practices”- Always request permissions first — Call
RequestPermissionsbefore reading data - Use appropriate intervals —
Interval.Daysfor summaries,Interval.Hoursfor detailed breakdowns - Handle empty results — Check
.Any()before calling.Average()to avoidInvalidOperationException - Use CancellationToken — Pass cancellation tokens for long-running queries
- Sum vs Average — Use
.Sum()for cumulative metrics (steps, calories, distance, hydration, sleep) and.Average()for point-in-time metrics (heart rate, weight, height, body fat, O2 sat, resting HR) - Blood pressure is special — It returns
BloodPressureResult(notNumericHealthResult) with separateSystolicandDiastolicvalues