Apple Health, dünya genelinde milyonlarca kullanıcının sağlık verilerini sakladığı merkezi platform. HealthKit framework'ü ile bu verilere erişerek, sağlık ve fitness uygulamaları geliştirebilirsin. Kalp atış hızından adım sayısına, uyku analizinden workout takibine kadar kapsamlı bir API sunar.
💡 Hızlı Not: HealthKit kullanmak için Apple Developer Program üyeliği ve uygulamada HealthKit capability'si aktif edilmeli. Ayrıca App Store Review Guidelines 5.1.3 — sağlık verilerinin reklam amaçlı kullanılması yasaktır.
İçindekiler
- HealthKit Temel Kavramlar
- Authorization ve İzinler
- Sağlık Verisi Okuma
- Sağlık Verisi Yazma
- HKQuery Tipleri
- Workout Sessions
- Background Delivery
- SwiftUI Charts ile Görselleştirme
- watchOS Entegrasyonu
- Privacy Best Practices
HealthKit Temel Kavramlar {#temel-kavramlar}
Kavram | Açıklama | Örnek |
|---|---|---|
HKObjectType | Veri tipi tanımı | steps, heartRate, sleep |
HKQuantityType | Sayısal değerler | adım (count), kalori (kcal) |
HKCategoryType | Kategorik değerler | uyku durumu, adet döngüsü |
HKSample | Tek veri noktası | 10:00'da 72 bpm kalp atışı |
HKStatistics | İstatistik | Günlük toplam adım |
HKUnit | Ölçü birimi | count, kcal, mg/dL |
Authorization ve İzinler {#authorization}
swift
1import HealthKit2 3class HealthKitManager {4 let healthStore = HKHealthStore()5 6 // Okuma ve yazma izinleri7 func requestAuthorization() async throws {8 guard HKHealthStore.isHealthDataAvailable() else {9 throw HealthError.notAvailable10 }11 12 let readTypes: Set<HKObjectType> = [13 HKQuantityType(.stepCount),14 HKQuantityType(.heartRate),15 HKQuantityType(.activeEnergyBurned),16 HKQuantityType(.distanceWalkingRunning),17 HKCategoryType(.sleepAnalysis),18 HKQuantityType(.bodyMass),19 ]20 21 let writeTypes: Set<HKSampleType> = [22 HKQuantityType(.stepCount),23 HKQuantityType(.activeEnergyBurned),24 HKQuantityType(.bodyMass),25 ]26 27 try await healthStore.requestAuthorization(toShare: writeTypes, read: readTypes)28 }29}Sağlık Verisi Okuma {#veri-okuma}
swift
1// Bugünün adım sayısı2func getTodaySteps() async throws -> Double {3 let stepType = HKQuantityType(.stepCount)4 let now = Date()5 let startOfDay = Calendar.current.startOfDay(for: now)6 let predicate = HKQuery.predicateForSamples(withStart: startOfDay, end: now)7 8 let statistics = try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<HKStatistics, Error>) in9 let query = HKStatisticsQuery(10 quantityType: stepType,11 quantitySamplePredicate: predicate,12 options: .cumulativeSum13 ) { _, statistics, error in14 if let error { continuation.resume(throwing: error) }15 else if let statistics { continuation.resume(returning: statistics) }16 else { continuation.resume(throwing: HealthError.noData) }17 }18 healthStore.execute(query)19 }20 21 return statistics.sumQuantity()?.doubleValue(for: .count()) ?? 022}23 24// Kalp atış hızı - son 7 gün25func getHeartRateData(days: Int = 7) async throws -> [(date: Date, bpm: Double)] {26 let heartRateType = HKQuantityType(.heartRate)27 let startDate = Calendar.current.date(byAdding: .day, value: -days, to: Date())!28 let predicate = HKQuery.predicateForSamples(withStart: startDate, end: Date())29 let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: true)30 31 return try await withCheckedThrowingContinuation { continuation in32 let query = HKSampleQuery(33 sampleType: heartRateType,34 predicate: predicate,35 limit: HKObjectQueryNoLimit,36 sortDescriptors: [sortDescriptor]37 ) { _, samples, error in38 if let error { continuation.resume(throwing: error); return }39 let results = (samples as? [HKQuantitySample])?.map { sample in40 (date: sample.startDate, bpm: sample.quantity.doubleValue(for: .init(from: "count/min")))41 } ?? []42 continuation.resume(returning: results)43 }44 healthStore.execute(query)45 }46}Sağlık Verisi Yazma {#veri-yazma}
swift
1// Kilo kaydet2func saveBodyMass(kg: Double, date: Date = Date()) async throws {3 let type = HKQuantityType(.bodyMass)4 let quantity = HKQuantity(unit: .gramUnit(with: .kilo), doubleValue: kg)5 let sample = HKQuantitySample(type: type, quantity: quantity, start: date, end: date)6 try await healthStore.save(sample)7}8 9// Workout kaydet10func saveWorkout(type: HKWorkoutActivityType, duration: TimeInterval, calories: Double) async throws {11 let workout = HKWorkout(12 activityType: type,13 start: Date().addingTimeInterval(-duration),14 end: Date(),15 duration: duration,16 totalEnergyBurned: HKQuantity(unit: .kilocalorie(), doubleValue: calories),17 totalDistance: nil,18 metadata: nil19 )20 try await healthStore.save(workout)21}HKQuery Tipleri {#query-tipleri}
Query | Kullanım | Özellik |
|---|---|---|
HKSampleQuery | Tek seferlik veri çekme | Basit okuma |
HKStatisticsQuery | İstatistik (sum, avg) | Toplam adım |
HKStatisticsCollectionQuery | Zaman serisi | Haftalık grafik |
HKAnchoredObjectQuery | Delta güncelleme | Son değişiklikler |
HKObserverQuery | Gerçek zamanlı | Canlı veri |
HKActivitySummaryQuery | Activity rings | Move/Exercise/Stand |
Workout Sessions {#workout}
swift
1// watchOS Workout Session2import HealthKit3 4class WorkoutManager: NSObject, HKWorkoutSessionDelegate, HKLiveWorkoutBuilderDelegate {5 let healthStore = HKHealthStore()6 var session: HKWorkoutSession?7 var builder: HKLiveWorkoutBuilder?8 9 func startWorkout(type: HKWorkoutActivityType) async throws {10 let config = HKWorkoutConfiguration()11 config.activityType = type12 config.locationType = .outdoor13 14 session = try HKWorkoutSession(healthStore: healthStore, configuration: config)15 builder = session?.associatedWorkoutBuilder()16 builder?.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore, workoutConfiguration: config)17 18 session?.delegate = self19 builder?.delegate = self20 21 let startDate = Date()22 session?.startActivity(with: startDate)23 try await builder?.beginCollection(at: startDate)24 }25 26 func endWorkout() async throws {27 session?.end()28 try await builder?.endCollection(at: Date())29 try await builder?.finishWorkout()30 }31 32 func workoutSession(_ workoutSession: HKWorkoutSession, didChangeTo toState: HKWorkoutSessionState, from fromState: HKWorkoutSessionState, date: Date) {33 // State değişikliği handle et34 }35 36 func workoutBuilderDidCollectEvent(_ workoutBuilder: HKLiveWorkoutBuilder) {37 // Yeni veri geldi38 }39}Background Delivery {#background}
swift
1// Uygulama arka plandayken sağlık verisi güncellemesi al2func enableBackgroundDelivery() {3 let stepType = HKQuantityType(.stepCount)4 healthStore.enableBackgroundDelivery(for: stepType, frequency: .hourly) { success, error in5 if success {6 print("Background delivery enabled for steps")7 }8 }9 10 // Observer query ile veri dinle11 let query = HKObserverQuery(sampleType: stepType, predicate: nil) { _, completionHandler, error in12 // Yeni adım verisi geldi - UI güncelle veya notification gönder13 self.refreshStepCount()14 completionHandler()15 }16 healthStore.execute(query)17}SwiftUI Charts ile Görselleştirme {#charts}
swift
1import SwiftUI2import Charts3 4struct StepChartView: View {5 let data: [(date: Date, steps: Int)]6 7 var body: some View {8 Chart(data, id: \.date) { item in9 BarMark(10 x: .value("Tarih", item.date, unit: .day),11 y: .value("Adım", item.steps)12 )13 .foregroundStyle(item.steps >= 10000 ? .green : .blue)14 }15 .chartYAxis {16 AxisMarks(position: .leading)17 }18 .frame(height: 200)19 }20}watchOS Entegrasyonu {#watchos}
Apple Watch, sağlık verilerinin birincil kaynağıdır. Watch Connectivity framework ile iPhone-Watch arası veri senkronizasyonu yapılabilir.
Privacy Best Practices {#privacy}
- Minimum veri iste — sadece gereken tipleri
- Açıklama ekle — Info.plist'te NSHealthShareUsageDescription ve NSHealthUpdateUsageDescription
- Şifreleme — sağlık verilerini iletirken TLS kullan
- Silme desteği — kullanıcı verilerini silebilmeli
- Reklam yasağı — sağlık verileri reklam amaçlı kullanılamaz (App Store guideline 5.1.3)
Easter Egg
Gizli bir bilgi buldun!
Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?
ALTIN İPUCU
Bu yazının en değerli bilgisi
Bu ipucu, yazının en önemli çıkarımını içeriyor.
Okuyucu Ödülü
Tebrikler! Bu yazıyı sonuna kadar okuduğun için sana özel bir hediyem var: **Kaynaklar:** - [Apple: HealthKit Documentation](https://developer.apple.com/documentation/healthkit) - [WWDC22: What's new in HealthKit](https://developer.apple.com/videos/play/wwdc2022/10005/) - [App Store Review Guidelines 5.1.3](https://developer.apple.com/app-store/review/guidelines/#health-and-health-research)

