StanfordSpezi / SpeziHealthKit

HealthKit module of the Stanford Spezi framework
https://swiftpackageindex.com/StanfordSpezi/SpeziHealthKit/documentation/
MIT License
15 stars 3 forks source link

Improve HealthKit Query Reusability #8

Open PSchmiedmayer opened 11 months ago

PSchmiedmayer commented 11 months ago

Use Case

The HealthKit component currently provides a good automated setup to collect HealthKit data that is defined in the Configuration of a Spezi application. Nevertheless, some Spezi applications need to create more custom queries and an improved setup that is more dynamic than the setup that is possible in the configuration.

Different Spezi Modules would also like to reuse the selective functionality of the HealthKit module in other mechanisms.

Problem

The HealthKit module provides a comprehensive implementation of several HealthKit queries that do not need to be reimplemented in Spezi applications with custom HealthKit queries. The current abstraction behind data sources provides a good encapsulation but limited extensibility.

Solution

We should add core parts of the functionalist as extensions to the existing HealthKit store types as well as the HealthKit queries. These extensions can be combined into a one-stop solution to query for HealthKit data, manage that query, and execute the query gathering a single result or an async sequence.

This abstraction should subsequentially be used in the HealthKit Module to power the automated Configuration-based API.

Alternatives considered

Input for alternatives is greatly appreciated. Please use the comments under this issue to discuss possible approaches and ideas. We are happy to support outside contributors who want to contribute to the Spezi ecosystem.

Additional context

No response

Code of Conduct

MihirJoe commented 3 months ago

@PSchmiedmayer Does this issue still need to be addressed?

PSchmiedmayer commented 3 months ago

@MihirJoe Yes, still, a great issue to look into.

The goal would be to make it easier to run one-off queries for HealthKit. Some use cases would allow you to easily display a chart showing the step counts from the last week, month, and year, as well as some UI to navigate between the weeks, months, and years.

Ideally, we provide a nice and convenient Swift type that can be used in a SwiftUI view that does the necessary query for HealthKit for us and provides the values in a convenient way. The query is re-evaluated if some of the configuration changes (e.g., the user jumps from a month view to a year view or switches between years), and the data is provided in a way that is easy to plot and interpret. HKSamples might still be the best way to make it accessible, but I could see some extensions on HKSample (or more specifically, a collection of HKSample sub-types) that would make it easier to plot this. The complete construct must use SwiftUI Observable and the new re-drawing mechanisms to make this efficient within a SwiftUI context.

A good way to get started would be to design a first example of how the API might be used by creating a common use case (as described above) and see how we can nicely extract this into smaller and then more reusable components. SwiftUI dynamic properties might also be a nice way to do this; I would suggest looking at SwiftData for some API inspirations.

MihirJoe commented 2 months ago

@PSchmiedmayer Thank you for providing these details. I have been diving deeper into this issue and have made some progress. I created a project from the template application to start playing around with how I want to query HealthKit data. Please see this repository: https://github.com/MihirJoe/SpeziTemplateApplication/tree/healthkit-reusability

So far, I have been able to effectively query Step Count data from the current day and also created an interactive Charts view where the user is able to select different date ranges (e.g. 7 days, 1 month, 3 months) and easily see their step count data. The README contains a simple diagram of the architecture and a short demo video of querying the step count data. I have plans of making this existing code a bit more reusable with other HKSample types and HKStatisticCollection types.

Of course, I will make a PR in the SpeziHealthKit module for you to review some of these changes, but it would be great to get your feedback on the initial functionality before I start solidifying some of the abstracted API implementation. Looking forward to your suggestions!