Overview
The Synheart Core Edge SDK is a watch-class build of Synheart Core targeted at Apple Watch, Wear OS, and other low-power wearables. It runs the session lifecycle (start / pause / resume / stop), captures HR + motion samples, and either streams the raw samples to a paired phone for HSI computation, or — when the native runtime binary is bundled — runs the edge HSI pipeline locally. Two language flavours, same API shape:SynheartCoreEdge(Swift) — for watchOS / iOS / macOS targetsai.synheart:synheart-core-edge(Kotlin) — for Wear OS / Android targets
edge feature) via FFI when present. When absent, both fall back to a STREAM mode that surfaces raw samples for the host to relay.
When to use Edge vs Core
Watches almost always run STREAM in production — the phone has more thermal headroom and a longer-running runtime. COMPUTE_LOCAL is for standalone-watch use cases (no phone reachable) and offline sessions.
Installation
Swift (SwiftPM)
Package.swift:
Kotlin (Gradle)
Until the SDK publishes to Maven Central, consume via composite build:Quickstart
Swift (watchOS)
HealthKitBiosignalProvider is constructed automatically using SynheartWear under the hood. Inject your own to override:
Kotlin (Wear OS)
HealthServicesBiosignalProvider) wraps Wear OS Health Services MeasureClient. It lives in the host app rather than the SDK because Wear platform binding is the host’s choice.
Engine API (both platforms)
currentHr: Double— latest HR sample (BPM)state: WatchSessionState—.idle | .starting | .running | .paused | .stopping | .syncing | .errorelapsedSec: Int,remainingSec: Int,pendingArtifacts: IntlastMetrics: [String: Any]?— frame metrics (hr_mean_bpm,hr_sdnn_ms,rmssd_ms,motion_rms_g)
- Kotlin:
engine.hrEvents(Flow),engine.events(Flow),engine.bioSamples(Flow, STREAM only) - Swift:
engine.onHrSample,engine.onEvent,engine.onBiosignalSample(callback assignments)
Mode resolution
WhenstartSession(...) is called with mode = nil (the default), the engine probes for the native runtime via the platform’s standard dynamic-symbol lookup:
- Runtime resolves → mode =
COMPUTE_LOCAL, HSI computed on-watch, artifacts go toEdgeOutbox - Runtime missing → mode =
STREAM, raw samples surfaced viabioSamples/onBiosignalSamplefor the host to relay to the phone
mode to force one path (e.g. .stream for low-battery preference, .computeLocal for standalone use).
Runtime native binary
Android (Wear OS)
libsynheart_core_runtime.so per ABI lives at wear/src/main/jniLibs/<abi>/:
:wear:vendorEdgeRuntime Gradle task that builds the edge runtime and drops the .so into jniLibs/. Pixel Watch 1 is 32-bit only — armeabi-v7a is sufficient.)
Apple (iOS + watchOS)
synheart/vendor/runtime/ios/:
Xcode picks the right slice per target automatically — the iOS app links the dynamic framework, the watchOS app links the static archive. The SDK’s
RuntimeBridge uses dlsym(RTLD_DEFAULT, …), so the watch’s statically-linked symbols resolve the same way as the iOS dylib’s dynamically-loaded ones.
Why two: Apple’s xcframework format prohibits mixing -framework and -library inputs in a single bundle, and the native runtime’s tier-3 watchOS target only emits a static library (not a dynamic one).
Building from source (runtime contributors): make ios-edge produces both. See the runtime repo for toolchain prerequisites.
Session lifecycle (RFC §8.1)
pause is host-driven (UI interruption, call, breath). Resume shifts startedAtMs forward by the paused interval so elapsed-time accounting skips the pause.
Compute provenance
Every HSI artifact the engine produces (inCOMPUTE_LOCAL mode) is stamped with a meta.synheart.compute block per the edge-tiering RFC:
See also
- Synheart Core (Kotlin SDK) — phone-class SDK
- Synheart Core (Swift SDK) — phone-class SDK
- Synheart Wear adapters — BLE HRM, HealthKit, Health Connect details
- HSI Specification — schema reference