HealthKit in iOS 27: Workout Zones, neue Typen
HealthKit trägt Herzfrequenzzonen für Workouts seit Jahren als inoffiziellen Bürger mit sich: Jede Lauf- und Radsport-App, die ein Balkendiagramm mit fünf Zonen zeichnete, berechnete diese Zonen selbst, zog rohe HKQuantitySample-Herzfrequenzwerte heran, ordnete sie fest codierten oder vom Benutzer eingegebenen Schwellenwerten zu und summierte die Zeit in jeder Zone von Hand. iOS 27 beendet die Eigenarbeit. Zonen werden zu einem strukturierten HealthKit-Typ, den das System erzeugt, den die Person in den Health-Einstellungen bearbeiten kann und den Ihre App mit bereits aufsummierter Zeit-in-Zone zurückliest. Dasselbe Release fügt zwei Kategorietypen zur reproduktiven Gesundheit hinzu, menopausalState und bleedingAfterMenopause, die eine Lücke im Zyklus-Tracking-Modell von HealthKit schließen.1
Zwei Fäden ziehen sich durch die Erweiterungen in iOS 27, und sie teilen dieselbe Form. Der Workout-Zonen-Faden nimmt Berechnungen, die Apps früher selbst besaßen, und verlagert sie in das Framework, wo die Zonendefinition einer Person über jede App hinweg konsistent bleibt, die danach fragt. Der Faden mit den neuen Typen gibt Lebensphasen, die HealthKit zuvor nicht abbilden konnte, ein typisiertes Kategorie-Sample. Beide folgen der bestehenden HealthKit-Grammatik: Quantity-Typen für gemessene Werte, Category-Typen für Ereignisse und Zustände. Dieser Beitrag geht jeden Punkt anhand von Apples Dokumentation durch, mit dem üblichen Rahmen des Clusters: was eine App, die HealthKit bereits ausliefert, hinzufügt, um die jeweilige Fähigkeit zu erlangen.
TL;DR
HKWorkoutZoneConfigurationdefiniert einen vollständigen Satz von Zonen für einen Quantity-Typ. Das System erzeugt Zonen automatisch aus den Gesundheitsmetriken einer Person, die Person kann sie in den Health-Einstellungen bearbeiten, und eine App kann benutzerdefinierte Zonen für ein bestimmtes Workout bereitstellen.2HKWorkoutZoneGroupkoppelt eine Zonenkonfiguration mit ihren Zeit-in-Zone-Daten. Sie lesen sie aus Instanzen abgeschlossener Workouts zurück, um die vom Framework bereits berechneten Dauern pro Zone zu erhalten, statt Herzfrequenz-Samples selbst zuzuordnen.3preferredWorkoutZoneConfiguration(for:)aufHKHealthStoregibt die bevorzugte Zonenkonfiguration der Person für einen Quantity-Typ zurück, sodass Ihre Diagramme mit den Schwellenwerten übereinstimmen, die sie überall sonst sieht.4menopausalStatezusammen mit der AufzählungHKCategoryValueMenopausalStateerfasst den menopausalen Zustand zu einem bestimmten Zeitpunkt; Start- und Enddatum des Samples müssen identisch sein, sonst schlägt das Speichern fehl.56bleedingAfterMenopauseerfasst postmenopausale Blutungen als Intervall mit einem Intensitätswert, klinisch klar getrennt vom Menstruationsfluss.7
Workout Zones mussten Sie schon immer selbst berechnen
Vor iOS 27 erledigte eine Workout-App, die Herzfrequenzzonen wollte, die gesamte Arbeit. Sie fragte HKQuantitySample-Herzfrequenzdaten für den Zeitraum des Workouts ab, entschied, wo die Zonengrenzen lagen (220 minus Alter, Prozentsätze der Laktatschwelle oder ein Wert, den der Benutzer in einen Einstellungsbildschirm eintippte), durchlief die Samples der Reihe nach und akkumulierte die in jedem Band verbrachten Sekunden. Jede App wählte ihre eigene Grenzwert-Mathematik, sodass eine Person, die mit zwei Apps lief, zwei verschiedene „Zone 3” sah. Keine der Zonendaten lag in HealthKit, also wurde nichts davon synchronisiert oder blieb portabel.
iOS 27 führt HKWorkoutZoneConfiguration ein, eine Struktur, die einen vollständigen Satz von Zonen für einen Quantity-Typ definiert.2 Die Konfiguration trägt ein geordnetes Array von Zonen und benennt den Quantity-Typ, für den sie gilt. Die Änderung, auf die es ankommt, betrifft den Ursprung der Zonen. Apples Dokumentation legt fest: Das System erzeugt Zonen automatisch auf Basis der Gesundheitsmetriken einer Person; die Person kann Zonen manuell in den Health-Einstellungen konfigurieren; oder eine App kann benutzerdefinierte Zonen für bestimmte Workouts bereitstellen.2 Zonendefinitionen sind nicht länger ein privates Detail jeder App, sondern werden zu geteiltem Zustand, der dem Framework gehört.
import HealthKit
let heartRateType = HKQuantityType(.heartRate)
// A custom configuration an app supplies for one workout.
// makeIntervalZones is your own builder; construct the configuration
// from the ordered zones your workout uses, per HKWorkoutZoneConfiguration's
// declaration. The configuration identifies the quantity type the zones apply to.
let configuration: HKWorkoutZoneConfiguration = makeIntervalZones(for: heartRateType)
Die zugehörige Struktur ist HKWorkoutZoneGroup, die Zonenkonfiguration und Zeit-in-Zone-Daten für einen Quantity-Typ enthält.3 Eine Zone Group kombiniert eine HKWorkoutZoneConfiguration mit den Zeitdaten pro Zone, sodass das Lesen einer Gruppe Ihnen sowohl die Grenzen als auch die Dauer liefert, die die Person in jeder verbracht hat. Apples Dokumentation beschreibt den Zugriff auf Zone Groups aus Instanzen abgeschlossener Workouts, um Zonendaten für beendete Workouts abzurufen, und aus einer Live-Workout-Quelle für Echtzeit-Zoneninformationen während einer aktiven Sitzung.3 Das Framework übernimmt die Zuordnung. Ihr Code liest das Ergebnis.
In Session 207 erklärt Apple, dass bei in HealthKit integrierten Workout-Zonen die Zeit in jeder Zone während des Workouts automatisch aus den eingehenden Samples berechnet wird, sodass die App vorab aufsummierte Dauern aus zoneGroupsByType liest, statt Herzfrequenz-Samples selbst zuzuordnen.8
import HealthKit
func summarize(_ group: HKWorkoutZoneGroup) {
// The group bundles the configuration (the zone boundaries)
// with the time-in-zone data the framework already computed.
let configuration = group.configuration
for zone in group.zones {
// Render each zone's accumulated time. No sample-walking,
// no manual bucketing — the durations arrive pre-summed.
render(zone)
}
}
Das dritte Element bindet die Konfiguration an die Person statt an die App. preferredWorkoutZoneConfiguration(for:) ist eine Instanzmethode auf HKHealthStore, die die bevorzugte Zonenkonfiguration einer Person für den angegebenen Quantity-Typ zurückgibt:4
func preferredWorkoutZoneConfiguration(
for quantityType: HKQuantityType
) async throws -> HKWorkoutZoneConfiguration?
Apples Dokumentation beschreibt den Rückgabevertrag genau: Die Methode liefert die manuell konfigurierten Zonen der Person aus den Health-Einstellungen zurück, oder die systemerzeugten Zonen, falls die Person keine benutzerdefinierten Werte gesetzt hat, oder nil, falls sie für diesen Quantity-Typ überhaupt keine Zonen konfiguriert hat.4 Systemerzeugte Zonen aktualisieren sich periodisch, wenn sich die Gesundheitsmetriken der Person ändern; von Hand gesetzte Zonen bleiben konstant, bis die Person sie erneut bearbeitet. Die dokumentierte Absicht ist, dass Apps Zoneninformationen anzeigen, die über jedes Workout hinweg mit den Präferenzen der Person übereinstimmen.4 Greifen Sie zu dieser Methode, wenn Ihre Zone 3 mit der Zone 3 übereinstimmen soll, die die Person überall sonst sieht, statt Ihre eigene zu erfinden.
import HealthKit
let store = HKHealthStore()
let heartRateType = HKQuantityType(.heartRate)
func loadPreferredZones() async throws -> HKWorkoutZoneConfiguration? {
// nil means the person has not configured zones for heart rate.
// Fall back to your own defaults only in that case.
try await store.preferredWorkoutZoneConfiguration(for: heartRateType)
}
Die Asymmetrie verdient eine Benennung. preferredWorkoutZoneConfiguration(for:) liest die dauerhafte Präferenz der Person, was vor, während und nach einem Workout konsistente Diagramme zeichnet. Eine benutzerdefinierte HKWorkoutZoneConfiguration, die Sie selbst erstellen, deckt den Fall ab, in dem ein bestimmtes Workout Zonen benötigt, die vom Standard der Person abweichen, etwa eine strukturierte Intervalleinheit mit eigenen Bändern. Die meisten Apps wollen die bevorzugte Konfiguration; der benutzerdefinierte Weg ist für die Fälle gedacht, in denen die Struktur eines Workouts eigene Zonen verlangt.
Neue Kategorietypen: menopausalState und bleedingAfterMenopause
Das Zyklus-Tracking-Modell von HealthKit handhabte die Menstruation, hatte aber keinen typisierten Weg, um festzuhalten, wo eine Person im menopausalen Übergang stand, und keinen Weg, um Blutungen festzuhalten, die nach dem Ende der Menstruation auftreten. iOS 27 fügt beide als Kategorietypen hinzu und folgt demselben HKCategorySample-Muster, das der iOS-26-HealthKit-Beitrag für Achtsamkeitssitzungen und Schlaf behandelte.
menopausalState ist ein Kategorietyp-Bezeichner für Samples, die den menopausalen Zustand einer Person erfassen.5 Jedes Sample ist ein Eintrag zu einem bestimmten Zeitpunkt, und Apples Dokumentation legt eine harte Bedingung fest: Das Startdatum muss dem Enddatum entsprechen, und das Speichern eines Samples, bei dem die beiden voneinander abweichen, erzeugt einen Fehler.5 Der Wert jedes Samples ist ein Fall der Aufzählung HKCategoryValueMenopausalState, die den menopausalen Zustand zu einem erfassten Zeitpunkt angibt.6 Da die Liste der Fälle aus dem Faktenblatt in Apples Darstellung ausgespart ist, behandeln Sie die Aufzählung als Quelle der Wahrheit für die gültigen Werte, statt die Namen der Fälle zu erraten; das dokumentierte Verhalten ist, dass jedes Sample einen solchen Fall zu einem bestimmten Datum speichert.6
import HealthKit
let store = HKHealthStore()
let menopausalType = HKCategoryType(.menopausalState)
func record(state: HKCategoryValueMenopausalState, on date: Date) async throws {
// Point-in-time sample: start and end MUST be identical.
// A mismatched start/end is a save error, by documented design.
let sample = HKCategorySample(
type: menopausalType,
value: state.rawValue,
start: date,
end: date
)
try await store.save(sample)
}
Das Punkt-in-der-Zeit-Modell prägt, wie Sie die Daten interpretieren. Apples Dokumentation weist darauf hin, dass Apps mehrere Samples über die Zeit lesen können, um übergeordnete Interpretationen abzuleiten: aktive Phasen, Übergänge oder einen aktuellen Zustand.6 Ein einzelnes Sample behauptet, dass ein bestimmter Zustand an einem bestimmten Datum galt, und das Framework überlässt die Arbeit, die Samples zu einer Zeitachse zusammenzufügen, der App. Apple rahmt jeden Eintrag als Zustandsänderung, als Bestätigung, dass ein Zustand zu diesem Datum galt, oder als beides, je nachdem, wie die App die Reihe liest.5
bleedingAfterMenopause ist ein Kategorietyp-Bezeichner für Samples, die Blutungen nach der Menopause erfassen.7 Die klinische Unterscheidung ist der Grund, warum es als eigener Typ existiert. Nach der Menopause ist die Menstruation beendet, sodass postmenopausale Blutungen kein Menstruationsfluss und keine intermenstruelle Blutung sind; Apples Dokumentation bezeichnet sie als klinisch verschieden von beidem.7 Anders als das Punkt-in-der-Zeit-Sample für den menopausalen Zustand repräsentiert ein bleedingAfterMenopause-Sample ein Blutungsintervall und speichert einen Intensitätswert.7
import HealthKit
let store = HKHealthStore()
let bleedingType = HKCategoryType(.bleedingAfterMenopause)
// `intensityValue` is the raw value of the intensity enum Apple defines for
// the bleedingAfterMenopause type; confirm the concrete case set in its declaration.
func record(intensityValue: Int, from start: Date, to end: Date) async throws {
// An interval sample, not point-in-time: start and end differ,
// and the value carries the bleeding intensity.
let sample = HKCategorySample(
type: bleedingType,
value: intensityValue,
start: start,
end: end
)
try await store.save(sample)
}
Die Aufteilung zwischen den beiden Typen spiegelt die Aufteilung wider, die der iOS-26-Beitrag zwischen Punkt-in-der-Zeit- und Intervall-Kategorie-Samples zog. menopausalState lässt sein Fenster auf einen einzigen Augenblick zusammenfallen und trägt einen Zustand. bleedingAfterMenopause behält ein echtes [start, end]-Fenster und trägt eine Intensität. Die falsche Form für eines von beiden zu wählen, ist ein Speicherfehler oder ein bedeutungsloser Datensatz, sodass der Typ, den Sie wählen, die Natur der Daten codiert, bevor Sie eine Zeile Abfragecode schreiben.
Adoptionspfad
Eine Workout- oder Gesundheits-App, die HealthKit bereits ausliefert, fügt die iOS-27-Oberfläche schrittweise hinzu; nichts davon schreibt die Autorisierungs- oder Sample-Speicher-Mechanik neu, die der iOS-26-Patterns-Beitrag behandelte.
- Löschen Sie Ihre Zonen-Mathematik. Jede App, die Herzfrequenzzonen von Hand berechnet, sollte
preferredWorkoutZoneConfiguration(for:)für den jeweiligen Quantity-Typ aufrufen und die zurückgegebene Konfiguration rendern, wobei sie nur dann auf Ihre eigenen Standardwerte zurückfällt, wenn der Aufrufnilzurückgibt.4 Ihre Zonen stimmen jetzt mit dem überein, was die Person systemweit sieht. - Lesen Sie
HKWorkoutZoneGroup, statt Samples zuzuordnen. Für Zusammenfassungen abgeschlossener Workouts ziehen Sie die Zone Group heran und rendern deren vorab berechnete Zeit-in-Zone-Daten, statt rohe Herzfrequenz-Samples zu durchlaufen und die Dauern selbst zu akkumulieren.3 - Stellen Sie eine benutzerdefinierte
HKWorkoutZoneConfigurationnur bereit, wenn ein Workout eigene Bänder benötigt. Strukturierte Intervalleinheiten mit maßgeschneiderten Zonen sind der Fall für eine benutzerdefinierte Konfiguration; alles andere nutzt die bevorzugte Konfiguration der Person.2 - Fügen Sie die neuen Kategorietypen zu Ihrer Autorisierungsanfrage hinzu. Eine Zyklus-Tracking-App fügt
menopausalStateundbleedingAfterMenopausezu ihren Schreib- und Lesemengen hinzu, erfasst dannmenopausalStateals Punkt-in-der-Zeit-Samples (Start gleich Ende) undbleedingAfterMenopauseals Intervall-Samples mit einer Intensität.57 - Prüfen Sie Ihre Start-/Enddaten je Typ. Das Speichern des menopausalen Zustands schlägt fehl, wenn Start und Ende abweichen; das Blutungs-Sample ist ein Intervall und erwartet, dass sie abweichen. Bringen Sie die Form des Fensters in Ordnung, bevor Sie den Speicherpfad ausliefern.57
FAQ
Muss ich in iOS 27 Herzfrequenzzonen weiterhin selbst berechnen?
Nein, nicht im Regelfall. preferredWorkoutZoneConfiguration(for:) gibt die bevorzugte Zonenkonfiguration der Person für einen Quantity-Typ zurück (ihre manuell konfigurierten Zonen aus den Health-Einstellungen, oder systemerzeugte Zonen, oder nil, falls sie keine konfiguriert hat), und HKWorkoutZoneGroup trägt die Zeit-in-Zone-Daten, die das Framework für ein Workout bereits berechnet hat.34 Zonen berechnen Sie nur dann selbst, wenn ein bestimmtes Workout benutzerdefinierte Bänder benötigt, die vom Standard der Person abweichen; in diesem Fall erstellen Sie eine HKWorkoutZoneConfiguration für dieses Workout.2
Was ist der Unterschied zwischen HKWorkoutZoneConfiguration und HKWorkoutZoneGroup?
HKWorkoutZoneConfiguration definiert einen vollständigen Satz von Zonen für einen Quantity-Typ: die geordneten Zonen und den Quantity-Typ, für den sie gelten.2 HKWorkoutZoneGroup enthält sowohl diese Konfiguration als auch die Zeit-in-Zone-Daten für einen Quantity-Typ, sodass eine Gruppe Ihnen die Grenzen nennt und wie lange die Person in jeder Zone verbracht hat.3 Sie lesen Zone Groups aus Instanzen abgeschlossener Workouts für beendete Sitzungen und aus einer Live-Quelle für Echtzeit-Zoneninformationen.3
Was gibt preferredWorkoutZoneConfiguration(for:) zurück, wenn die Person nie Zonen eingerichtet hat?
Sie gibt die systemerzeugten Zonen zurück, falls die Person keine benutzerdefinierten Werte gesetzt hat, und nil nur dann, falls die Person für diesen Quantity-Typ überhaupt keine Zonen konfiguriert hat.4 Wenn die Person Zonen manuell in den Health-Einstellungen gesetzt hat, gibt die Methode diese zurück, und sie bleiben konstant, bis die Person sie bearbeitet; systemerzeugte Zonen aktualisieren sich periodisch, wenn sich die Gesundheitsmetriken der Person ändern.4 Verzweigen Sie bei nil, um Ihre eigenen Ausweich-Standardwerte bereitzustellen.
Warum schlägt das Speichern eines menopausalState-Samples mit einem Datumsfehler fehl?
Weil menopausalState einen Zustand zu einem einzigen Zeitpunkt erfasst, verlangt das Framework, dass Start- und Enddatum des Samples identisch sind, und ein Sample, dessen Daten abweichen, erzeugt beim Speichern einen Fehler.5 Setzen Sie beide auf dasselbe Date. Diese Bedingung unterscheidet es von bleedingAfterMenopause, das ein Intervall repräsentiert und erwartet, dass Start und Ende abweichen.7
Wie unterscheidet sich bleedingAfterMenopause vom Menstruationsfluss?
Nach der Menopause ist die Menstruation beendet, sodass postmenopausale Blutungen klinisch verschieden vom Menstruationsfluss und von der intermenstruellen Blutung sind; Apple gibt ihnen aus diesem Grund einen eigenen Kategorietyp.7 Jedes bleedingAfterMenopause-Sample speichert ein Intervall und einen Intensitätswert, und für die zugehörige Zustandsverfolgung verwenden Sie den Typ menopausalState.7
Der vollständige Apple-Ecosystem-Cluster liegt neben diesem Beitrag: die iOS-26-Muster für HealthKit-Autorisierung und Sample-Typen, auf denen dieser aufbaut; der watchOS-Workout-Lebenszyklus, in dem Zonendaten während einer Live-Sitzung entstehen; der watchOS-Runtime-Vertrag, der die Hintergrundausführung am Handgelenk regelt; und die drei Oberflächen einer iOS-App, die HealthKit als Datenquellenschicht einordnen. Der Hub ist die Apple-Ecosystem-Serie. Für den breiteren Kontext von iOS mit KI-Agenten siehe den Leitfaden zur iOS-Agent-Entwicklung.
References
-
Apple Developer Documentation: HealthKit. The framework reference covering quantity types, category types, samples, and the iOS 27 workout-zone and reproductive-health additions. ↩
-
Apple Developer Documentation:
HKWorkoutZoneConfiguration(iOS 27.0). “A structure that defines a complete set of zones for a quantity type.” Declared asstruct HKWorkoutZoneConfiguration; contains an ordered array of zones, identifies its quantity type, and supports system-generated, person-configured, or app-supplied custom zones. ↩↩↩↩↩↩ -
Apple Developer Documentation:
HKWorkoutZoneGroup(iOS 27.0). “A structure that contains zone configuration and time-in-zone data for a quantity type.” Declared asstruct HKWorkoutZoneGroup; combines a configuration with time-in-zone data, accessible from completed-workout instances and from live-workout sources. ↩↩↩↩↩↩↩ -
Apple Developer Documentation:
preferredWorkoutZoneConfiguration(for:)(iOS 27.0). “Returns someone’s preferred zone configuration for the specified quantity type.” Declared asfunc preferredWorkoutZoneConfiguration(for quantityType: HKQuantityType) async throws -> HKWorkoutZoneConfiguration?; returns manually configured zones, system-generated zones, ornil. ↩↩↩↩↩↩↩↩ -
Apple Developer Documentation:
menopausalState(iOS 27.0). “An identifier for samples that record a person’s menopausal state.” Declared asstatic let menopausalState: HKCategoryTypeIdentifier; point-in-time samples require identical start and end dates or the save fails. ↩↩↩↩↩↩↩ -
Apple Developer Documentation:
HKCategoryValueMenopausalState(iOS 27.0). “A value that indicates the menopausal state at a recorded point in time.” Declared asenum HKCategoryValueMenopausalState; apps can query multiple samples over time to derive active periods, transitions, or current state. ↩↩↩↩ -
Apple Developer Documentation:
bleedingAfterMenopause(iOS 27.0). “An identifier for samples that record bleeding after menopause.” Declared asstatic let bleedingAfterMenopause: HKCategoryTypeIdentifier; clinically distinct from menstrual flow, each sample is an interval with an intensity value. ↩↩↩↩↩↩↩↩↩ -
Apple, WWDC26 session 207, “Deliver workout insights with HealthKit workout zones.” developer.apple.com/videos/play/wwdc2026/207. With heart rate and cycling power zones integrated into HealthKit in iOS 27, the time in each zone is calculated automatically based on incoming samples during the workout, and an app reads it back from the
zoneGroupsByTypedictionary onHKWorkoutorHKWorkoutActivity. ↩