My Heart Counts (MHC) application is a Spezi-based large-scale cardiovascular study application, developed at Stanford University.
Key features include:
- Schedule-based, user-actionable tasks and content, such as surveys, active tasks, or informative articles
- Active tasks, for example a Six Minute Walk Test and a Twelve Minute Run Test
- Automatic data collection through Apple’s SensorKit and HealthKit frameworks
- MHC Heart Health Dashboard, which provides an overview of the participant’s overall health, computed from eight metrics read from HealthKit and survey responses
- Physical Activity Trial with personalized coaching messages
- Large Language Model (LLM) generated personalized physical activity nudges
|
|
|
| Home | Heart Health Surveys | Heart Health Dashboard |
|
|
|
| Active Tasks (6 Minute Walk Test and 12 Minute Run Test) | Detailed Health Stats | Spanish Language Support |
This repository contains the My Heart Counts (MHC) iOS application, which is implemented using the Spezi ecosystem and builds on top of the Stanford Spezi Template Application.
[!NOTE] Do you want to learn more about the Stanford Spezi Template Application and how to use, extend, and modify this application? Check out the Stanford Spezi Template Application documentation.
In order to run and develop the My Heart Counts app locally, you'll need the following:
- Clone this repository
- A firebase environment
- A study bundle
- The app itself (either in the simulator or on a real device)
- Go to the definitions submodule:
cd MyHeartCounts-StudyDefinitions - Run
swift run MHCStudyDefinitionExporterCLI export ..to generate a study bundle- This will place a
mhcStudyDefinition.spezistudybundle.aarfile in the root of the MyHeartCounts-iOS repo - you can have it saved elsewhere by replacing the
..with the path of the folder where you want the study definition to be placed
- This will place a
- Go to the firebase submodule:
cd MyHeartCounts-Firebase - Run
npm run prepare - Run
npm run serve:seeded
- Disable SensorKit and adjust the Codesign options
- (You can skip this step if you have access to a Stanford-generated provisioning profile and have Stanford's codesign certificate installed locally.)
- Open
MyHeartCounts.entitlementsand remove thecom.apple.developer.sensorkit.reader.allowentry - Change the bundle identifiers in all targets (e.g., by adding a custom prefix)
- Note: you'll also need to edit the watch app's Info.plist and adjust the
WKCompanionAppBundleIdentifierentry
- Note: you'll also need to edit the watch app's Info.plist and adjust the
- Select your own development team in the MyHeartCounts and MyHeartCountsWatchApp targets, and enable the automatic code signing option
- Adjust the app's run configuration (open via
cmd+shift+,) and enable the following options:--useFirebaseEmulator- If you wish to use a custom firebase deployment instead of a local emulator, you'll need to use the
--overrideFirebaseConfig plist=nameflag instead, wherenameis either an absolute path of a GoogleService-Info.plist file (this will only work in the simulator), or the filename (without extension) of a GoogleService-Info.plist file bundled with the app.
- If you wish to use a custom firebase deployment instead of a local emulator, you'll need to use the
--studyBundle- Specify the absolute path of the
.aarfile generated above - Note: if you're running the app on a physical device, specifying the file location on the Mac won't work, since the iPhone can't access that. Instead, you can do one of the following:
- Bundle the study definition into the app:
- Drag the
.aarfile into the app's Resources folder in Xcode - Adjust the code in the
StudyBundleLoadertype to simply always load from that in-bundle URL
- Drag the
- Host the study definition using the Firebase storage emulator:
- Open the Storage emulator (likely at http://localhost:4000/storage)
- Upload the
mhcStudyBundle.spezistudybundle.aarfile to the/publicfolder - Configure the
--studyBundleargument to point tohttp://HOSTNAME.local:9199/v0/b/myheart-counts-development.appspot.com/o/public%2FmhcStudyBundle.spezistudybundle.aar?alt=media- Note that you'll need to replace
HOSTNAMEwith your Mac's local-network name (you can find this in Settings.app → General → Sharing → Local hostname)
- Note that you'll need to replace
- Bundle the study definition into the app:
- Specify the absolute path of the
--disableAutomaticBulkHealthExport- (this option will disable the historical health data collection, improving performance when running the app on a real device)
- Run the application in Xcode.
In Debug builds, simulator builds, and TestFlight installations, select United Kingdom during eligibility screening, enter pls let me in anyway in the Coming Soon screen's email field, and tap Notify Me to test the UK study using the US Firebase configuration.
The phrase is not sent to the waiting list. Continue through account setup with your usual test-account credentials.
The app tracks the Imperial study variant separately from its US Firebase backend and uses the UK study locale. Without the phrase, UK selection keeps the normal "Coming Soon" behavior.
Both selections stay in memory until final study enrollment begins, when they are saved as enrolledStudyVariant and the existing lastUsedFirebaseConfig preference. Quitting before that step allows a fresh region selection on relaunch.
At launch, an existing backend preference without a study variant defaults to Stanford; the backend preference is left unchanged. Older UK test installations that stored region(GB) should reset their local data before using this approach.
The feature flag only controls access to the temporary enrollment path. Removing it or adding a UK backend does not change an enrolled participant's saved backend or variant.
Both variants use the shared public/mhcStudyBundle.spezistudybundle.tar.zst archive in the connected backend's bucket and the existing app-bundled fallback if the hosted archive cannot be decoded.
Study resources are resolved within that bundle using the variant's study locale.
UK consent still requires an en-GB consent resource in the shared bundle; the checked-in bundle currently only includes US consent resources.
News is also selected by study variant: Stanford uses public/news/, and Imperial uses public/news-UK/ in the connected backend's bucket. Publish Imperial articles there; an empty feed does not fall back to Stanford news.
Articles can specify a headerImage in their metadata. Without one, Stanford keeps its existing default image and Imperial uses no institutional image.
When advancing account onboarding after creation/login, the app fills in a missing studyVariant field (stanford or imperial) from the selected variant; an existing account value takes precedence. Startup uses the local variant cache, then synchronizes the active variant and study locale when complete account details arrive. For enrolled sessions, this also refreshes enrolledStudyVariant; missing account metadata leaves the cache unchanged. Synchronization never changes or persists a backend selection.
Temporary Imperial accounts on the US backend are disposable: delete and recreate them when moving to the real UK deployment, and reset the app's local data.
For Release builds on a device, the temporary feature requires the TestFlight sandbox receipt.
Note
Please make sure not to commit and push any of the SensorKit, Code Signing, and run argument changes listed above; these changes are only required for local development.
Contributions to this project are welcome. Please make sure to read the contribution guidelines and the contributor covenant code of conduct first. You can find a list of contributors in the CONTRIBUTORS.md file.
This project is licensed under the MIT License. See LICENSE.md for more information.
If you use this software, please cite it using the metadata in CITATION.cff, which GitHub surfaces through the Cite this repository button.
For more information, visit the Schmiedmayer Lab GitHub organization.













