A professional cycling and fitness application with Bluetooth heart rate monitor integration, real-time BPM tracking, advanced training metrics (TRIMP, TSS), and comprehensive workout history with chart visualization.
PowerHeartTracker is an advanced fitness tracking app designed for serious athletes and cyclists. It connects to Bluetooth Low Energy (BLE) heart rate monitors, tracks workouts in real-time with animated visualizations, calculates sophisticated training metrics, and maintains detailed workout history for performance analysis.
- BLE Heart Rate Monitor: Connect to Bluetooth HR sensors
- Real-Time Display: Live BPM with animated heart icon
- Workout Tracking: Start/stop sessions with detailed metrics
- Live Charts: Real-time heart rate graph during workouts
- Workout History: Comprehensive past workout database
- Heart Rate Zones: Automatic zone calculation and analysis
- TRIMP: Training Impulse for workout intensity quantification
- TSS: Training Stress Score for cycling-specific load
- kJ: Kilojoules (energy expenditure calculation)
- Average HR: Mean heart rate across workout
- Max HR: Peak heart rate detection
- Duration: Precise workout timing
- FTP: Functional Threshold Power configuration
- Max HR: Maximum heart rate personalization
- Resting HR: Baseline heart rate setting
- Custom Zones: Personalized training zones
- Framework: SwiftUI
- BLE Communication: CoreBluetooth (CBCentralManager, CBPeripheral)
- Data Persistence: SwiftData with custom transformers
- Charts: SwiftUI Charts framework
- iOS Version: iOS 17+
- Architecture: MVVM with HeartRateService (BLE manager)
- Custom Transformers: IntArrayJSONTransformer for array storage
This project demonstrates:
- CoreBluetooth framework integration
- BLE device scanning and connection
- Heart Rate Service (0x180D) protocol
- SwiftData with custom value transformers
- Real-time chart visualization
- Complex training metric calculations
- Background BLE updates
- State management for connected peripherals
PowerHeartTracker/
├── App/
│ └── HRPowerTrackerApp.swift # App entry point
├── Models/
│ ├── Workout.swift # SwiftData workout model
│ └── UserPrefs.swift # User preferences
├── Services/
│ └── HeartRateService.swift # CoreBluetooth manager
├── ViewModels/
│ └── HeartRateViewModel.swift # MVVM view model
├── Views/
│ ├── Screens/
│ │ ├── RecordView.swift # Active workout tracking
│ │ ├── HistoryView.swift # Past workouts
│ │ ├── SettingsView.swift # User preferences
│ │ └── WorkoutDetailView.swift # Detailed stats
│ └── Components/
│ └── WattsForm.swift # Power input
└── Utilities/
└── IntArrayJSONTransformer.swift # Custom transformer
Any BLE-compatible heart rate monitor supporting:
- Service UUID: 0x180D (Heart Rate Service)
- Characteristic UUID: 0x2A37 (Heart Rate Measurement)
- Polar H10, H9, OH1
- Garmin HRM-Dual, HRM-Pro
- Wahoo TICKR, TICKR X
- Apple Watch (via BLE broadcasting)
- Any ANT+ HR monitor with BLE bridge
- Service UUID: 0x1818 (Cycling Power Service)
- Supports cycling power meters for precise TSS calculation
class HeartRateService: NSObject, ObservableObject {
private var centralManager: CBCentralManager!
@Published var currentHeartRate: Int = 0
@Published var isConnected: Bool = false
func startScanning() {
centralManager.scanForPeripherals(
withServices: [CBUUID(string: "180D")],
options: nil
)
}
func didUpdateValueFor(characteristic: CBCharacteristic) {
// Parse heart rate data
// Update published properties
}
}@objc(IntArrayJSONTransformer)
class IntArrayJSONTransformer: NSSecureUnarchiveFromDataTransformer {
// Transforms [Int] to Data for SwiftData storage
// Stores heart rate arrays as JSON
}func calculateTRIMP(avgHR: Int, duration: TimeInterval, restingHR: Int, maxHR: Int) -> Double {
let hrReserve = Double(avgHR - restingHR) / Double(maxHR - restingHR)
let minutes = duration / 60
return minutes * hrReserve * 0.64 * exp(1.92 * hrReserve)
}func calculateTSS(avgHR: Int, duration: TimeInterval, ftp: Int) -> Double {
let normalizedPower = Double(avgHR) * 0.95 // Approximation
let intensityFactor = normalizedPower / Double(ftp)
let hours = duration / 3600
return hours * intensityFactor * intensityFactor * 100
}- Proper resource cleanup with
deinitmethods - Bounded data structures to prevent memory overflow
- Timer management with weak references
- CoreBluetooth lifecycle management
- MVVM Architecture: Clean separation of concerns
- Publisher-Subscriber: Reactive data flow with Combine
- Dependency Injection: Services injected into views
- Repository Pattern: Data persistence abstraction
- CoreBluetooth framework mastery
- BLE peripheral management
- Heart Rate Service protocol parsing
- SwiftData custom value transformers
- Real-time data visualization
- Advanced fitness metrics algorithms
- Background BLE updates
- State synchronization (BLE ↔ SwiftUI)
- Chart animations and updates
- Performance optimization for continuous updates
Quantifies workout intensity considering heart rate, duration, and individual HR zones. Higher TRIMP = more intense workout.
Cycling-specific metric estimating training load. 100 TSS ≈ 1 hour at FTP (Functional Threshold Power).
Energy expenditure estimate based on heart rate and duration. Approximates calories burned.
- Zone 1: 50-60% max HR (Recovery)
- Zone 2: 60-70% max HR (Endurance)
- Zone 3: 70-80% max HR (Tempo)
- Zone 4: 80-90% max HR (Threshold)
- Zone 5: 90-100% max HR (VO2 Max)
- Cycling training management
- Running workout tracking
- HIIT session monitoring
- Endurance athlete training logs
- Heart rate zone training
- Performance analysis over time
- Sortable by date
- Filterable by metrics
- Detailed view with charts
- Export capabilities (planned)
- Statistics summaries
- iOS 17.0+
- Xcode 15.0+
- Bluetooth Low Energy capable device
- Heart rate monitor with BLE support
- Open
WhoopConnectApp.xcodeprojin Xcode - Ensure your device has Bluetooth enabled
- Build and run the project
- Configure settings (max HR, resting HR, FTP)
- Connect a BLE heart rate monitor
- Start recording workouts!
User preferences can be configured in the Settings tab:
- Resting Heart Rate (for TRIMP calculation)
- Maximum Heart Rate (for heart rate zones)
- Functional Threshold Power (for TSS calculation)
- Power meter integration (ANT+/BLE)
- GPS tracking integration
- HealthKit synchronization
- Training plan builder
- Workout exports (FIT, TCX, GPX files)
- Social sharing features
- Cloud backup and sync
- Multi-device support
- Coach/athlete data sharing
Ensure Bluetooth permissions in Info.plist:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>Connect to heart rate monitors</string>Author: Martynas Prascevicius Contact: mpcode@icloud.com Purpose: Advanced project demonstrating CoreBluetooth and fitness metrics