{"id":50755758,"url":"https://github.com/megabyte0x/healthykit","last_synced_at":"2026-06-19T00:30:43.934Z","repository":{"id":361949204,"uuid":"1254745478","full_name":"megabyte0x/healthykit","owner":"megabyte0x","description":"Native HealthKit sync app with a private REST backend","archived":false,"fork":false,"pushed_at":"2026-06-02T00:26:01.000Z","size":933,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-02T01:09:13.772Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/megabyte0x.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-31T00:31:27.000Z","updated_at":"2026-06-02T00:26:04.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/megabyte0x/healthykit","commit_stats":null,"previous_names":["megabyte0x/healthykit"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/megabyte0x/healthykit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/megabyte0x%2Fhealthykit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/megabyte0x%2Fhealthykit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/megabyte0x%2Fhealthykit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/megabyte0x%2Fhealthykit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/megabyte0x","download_url":"https://codeload.github.com/megabyte0x/healthykit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/megabyte0x%2Fhealthykit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34513020,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-11T05:00:25.538Z","updated_at":"2026-06-19T00:30:43.927Z","avatar_url":"https://github.com/megabyte0x.png","language":"Swift","funding_links":[],"categories":["Health","Open source apps"],"sub_categories":["SpriteKit","iOS"],"readme":"# HealthSync\n\nHealthSync is a native SwiftUI iOS app that reads selected Apple Health data on-device through HealthKit and syncs queued JSON batches to a private REST backend.\n\nThere is no iCloud or server-side Apple Health REST API. Apple Health reads happen only on the iPhone after the user grants HealthKit read permissions. Health data stays on-device until the user configures a backend URL and auth token.\n\nWebsite: https://healthysync.megabyte.sh\n\nApple Health app sync guide: https://healthysync.megabyte.sh/apple-health-app-sync\n\nPrivacy policy: https://healthysync.megabyte.sh/privacy\n\nSupport: https://healthysync.megabyte.sh/support\n\n## What It Syncs\n\n- Steps, heart rate, resting heart rate, HRV SDNN\n- Active energy, basal energy\n- Body mass, body fat percentage\n- Sleep analysis\n- Workouts\n- Optional dietary energy, macros, and water when available\n\nThe app requests read-only HealthKit permissions. It does not request write permissions, does not include analytics, and does not use third-party telemetry or health SDKs.\n\n## Setup\n\nPrerequisites:\n\n- macOS with Xcode 16 or newer\n- An iOS 17+ simulator or a real iPhone for HealthKit testing\n- Python 3.11+ for backend scripts and tests\n- Docker Desktop if you want the local Postgres backend\n\nFrom the repo root, open the iOS project:\n\n```bash\nopen HealthSync.xcodeproj\n```\n\nIn Xcode, select the `HealthSync` target, set your development team for signing, confirm the HealthKit capability is enabled, then build for an iOS 17+ simulator or device.\n\nFor local persistent sync storage, copy the backend environment template and generate separate secrets for the app ingest token and hosted-token HMAC secret:\n\n```bash\ncp .env.example .env\npython3 -m backend.scripts.generate_token\npython3 -m backend.scripts.generate_token\n```\n\nEdit `.env`, replace `POSTGRES_PASSWORD`, paste the first generated value as `API_TOKEN`, paste the second generated value as `TOKEN_HASH_SECRET`, and keep `.env` uncommitted. Start the local API and Postgres stack:\n\n```bash\ndocker compose up --build\n```\n\nConfigure HealthSync settings with:\n\n- Simulator backend URL: `http://127.0.0.1:8080`\n- Real iPhone local test URL: `http://\u003cmac-lan-ip\u003e:8080`\n- Production URL: an HTTPS endpoint\n- Auth token: the same value as backend `API_TOKEN`\n\nRun the backend test setup when changing persistence code:\n\n```bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r backend/requirements.txt\npython3 -m pytest Tests/backend/test_backend_api.py -q\n```\n\n## Backend Contract\n\nThe app posts to:\n\n```text\nPOST {configured_backend_url}/api/apple-health/sync\n```\n\nHeaders:\n\n```text\nAuthorization: Bearer {token_from_keychain}\nContent-Type: application/json\nX-Device-Id: {stable_local_device_id}\nX-App-Version: {app_version}\n```\n\nEvery metric and workout uses a deterministic ID of `healthkit:{sample_uuid}`. Every upload batch has its own `export_id`, and failed batches remain queued locally for retry.\n\n## Local Persistence\n\nThe app uses SQLite for settings, selected data types, sync frequency, HealthKit anchors, queued upload batches, sync logs, and the stable local device ID. Auth tokens are stored only in Keychain.\n\nSuccessful batches are marked uploaded and pruned after 7 days. Failed network/server uploads remain queued.\n\n## Open And Build\n\n1. Open `HealthSync.xcodeproj` in Xcode 16 or newer.\n2. Select the `HealthSync` target.\n3. Set your development team for signing.\n4. Confirm the HealthKit capability is enabled.\n5. Build for an iOS 17+ simulator or device.\n\nCLI build:\n\n```bash\nxcodebuild build -project HealthSync.xcodeproj -scheme HealthSync -destination 'generic/platform=iOS Simulator' -derivedDataPath .DerivedData CODE_SIGNING_ALLOWED=NO\n```\n\n## Run Tests\n\nBuild tests without launching a simulator:\n\n```bash\nxcodebuild build-for-testing -project HealthSync.xcodeproj -scheme HealthSync -destination 'generic/platform=iOS Simulator' -derivedDataPath .DerivedData CODE_SIGNING_ALLOWED=NO\n```\n\nRun the full XCTest suite with an available simulator:\n\n```bash\nxcodebuild test -project HealthSync.xcodeproj -scheme HealthSync -destination 'platform=iOS Simulator,name=iPhone 16' -derivedDataPath .DerivedData CODE_SIGNING_ALLOWED=NO\n```\n\n## Persistent Backend\n\nFor real persistent storage, use the backend in `backend/`. It stores uploaded HealthSync data in Postgres and exposes fetch endpoints for metrics, workouts, and sync batches.\n\nFastest local setup:\n\n```bash\ncp .env.example .env\npython3 -m backend.scripts.generate_token\n```\n\nIn `.env`, replace only these local Docker values: `POSTGRES_PASSWORD`, `API_TOKEN`, and `TOKEN_HASH_SECRET`. Paste the generated token as `API_TOKEN`, run the generator again, paste the second token as `TOKEN_HASH_SECRET`, then run:\n\n```bash\ndocker compose up --build\n```\n\nUse `http://127.0.0.1:8080` from the simulator. For a real iPhone, use a private HTTPS endpoint reachable from the phone, or use your Mac's LAN address for same-Wi-Fi testing.\n\nFor hosted HealthSync on Supabase Postgres, deploy the FastAPI backend with `DATABASE_URL`, `API_TOKEN`, `TOKEN_HASH_SECRET`, `HOSTED_PUBLIC_BASE_URL`, and `HOSTED_PROVISIONING_ENABLED=true`. The backend provisions HealthSync workspaces and returns an app ingest token plus a private read-only agent endpoint/token. The app's hosted setup flow uses the hosted backend URL and ingest token; AI agents should receive only the agent endpoint and agent token, never Supabase credentials.\n\nFor Supabase, Neon, or another managed Postgres database without hosted provisioning, set `DATABASE_URL`, `API_TOKEN`, and `TOKEN_HASH_SECRET`, run `alembic upgrade head`, and deploy `uvicorn backend.main:app`. See `backend/README.md` for the full setup, hosted provisioning, and fetch API examples.\n\n## Backend Stub\n\nThe `backend_stub/` service is still available as a local-only request-shape stub. It does not persist data.\n\n```bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r backend_stub/requirements.txt\nuvicorn backend_stub.main:app --host 0.0.0.0 --port 8080\n```\n\nFor a real iPhone on the same Wi-Fi as this Mac, use the Mac's LAN address instead, for example:\n\n```text\nhttp://192.168.1.24:8080\n```\n\niOS may ask for Local Network access the first time the app connects to a LAN backend. Allow it for local testing.\n\n## App Setup\n\n1. Launch the app.\n2. Tap **Connect Apple Health** and grant read permissions.\n3. Open **Settings**.\n4. Enter the backend URL.\n5. Enter the auth token. It is saved in Keychain.\n6. Choose data type toggles and sync frequency.\n7. Tap **Test connection**.\n8. Tap **Sync last 24 hours** or open **Backfill date range**.\n\n## Background Limitations\n\nHealthSync uses `HKObserverQuery` and HealthKit background delivery where iOS permits it. It also supports hourly/daily best-effort sync while the app is alive. iOS does not guarantee background sync timing, especially while the phone is locked, in Low Power Mode, recently rebooted, or when the system suppresses background work.\n\nManual sync and backfill are the reliable paths.\n\n## Deployment Notes\n\n- Test HealthKit permissions on a real iPhone. Simulators are useful for UI and unit tests but do not represent real Apple Health data availability.\n- Use HTTPS for production backends.\n- The backend should dedupe by `device_id`, `export_id`, and record IDs.\n- The app never prints auth tokens or raw health payloads to console logs.\n\n## TestFlight Access Web App\n\nThe `web/` directory contains a small Next.js app where testers can request HealthSync TestFlight access.\n\n```bash\ncd web\nnpm install\nnpm run dev\n```\n\nLocal requests are appended to `web/data/testflight-requests.jsonl`, which is ignored by git. Set `TESTFLIGHT_REQUEST_WEBHOOK_URL` to forward validated requests to a production workflow.\n\nProduction deployments should use durable storage. The Vercel deployment stores requests in private Vercel Blob records when Blob env vars are configured, and exposes a bearer-token-protected admin export at `/api/access-requests`. See `web/README.md` for Vercel setup, health checks, and export commands.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmegabyte0x%2Fhealthykit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmegabyte0x%2Fhealthykit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmegabyte0x%2Fhealthykit/lists"}