案例:跨平台的健康数据仪表盘
概述
本案例将演示如何使用 SwiftUI 构建一个跨平台(iOS、watchOS、macOS)的健康数据仪表盘,包含多种图表类型(折线图、环形图、柱状图)和平台适配逻辑。
实现步骤
1. 设计跨平台数据模型
struct HealthMetric: Identifiable {
let id = UUID()
let date: Date
let value: Double
let type: MetricType
enum MetricType: String, CaseIterable {
case steps, heartRate, sleep
}
}
class HealthDataStore: ObservableObject {
@Published var metrics: [HealthMetric] = []
// 模拟数据加载
func loadData() async {
// 从 HealthKit 或 API 获取真实数据
let mockData = generateMockData()
DispatchQueue.main.async {
self.metrics = mockData
}
}
}
2. 创建共享图表组件
struct HealthLineChart: View {
let data: [HealthMetric]
let type: HealthMetric.MetricType
var body: some View {
Chart(data.filter { $0.type == type }) { metric in
LineMark(
x: .value("Date", metric.date),
y: .value("Value", metric.value)
)
.foregroundStyle(by: .value("Type", type.rawValue))
}
.chartXAxis {
AxisMarks(values: .stride(by: .day)) { value in
AxisGridLine()
AxisTick()
AxisValueLabel(format: .dateTime.day())
}
}
}
}
3. 平台特定适配
iOS 主仪表盘
struct iOSHealthDashboard: View {
@StateObject private var store = HealthDataStore()
var body: some View {
TabView {
VStack {
HealthLineChart(data: store.metrics, type: .steps)
RingChart(data: store.metrics)
}
.tabItem { Label("Summary", systemImage: "heart.fill") }
}
.task { await store.loadData() }
}
}
watchOS 精简版
struct WatchOSHealthView: View {
@StateObject private var store = HealthDataStore()
var body: some View {
ScrollView {
HealthLineChart(data: store.metrics, type: .heartRate)
.frame(height: 120)
BarChart(data: store.metrics)
.frame(height: 80)
}
.task { await store.loadData() }
}
}
macOS 详细视图
struct MacHealthDashboard: View {
@StateObject private var store = HealthDataStore()
var body: some View {
HSplitView {
List(HealthMetric.MetricType.allCases, id: \.self) { type in
NavigationLink(type.rawValue) {
HealthLineChart(data: store.metrics, type: type)
.frame(minWidth: 400)
}
}
.frame(minWidth: 200)
DetailView(metrics: store.metrics)
}
.task { await store.loadData() }
}
}
4. 响应式布局处理
@main
struct HealthApp: App {
var body: some Scene {
#if os(iOS)
WindowGroup {
iOSHealthDashboard()
}
#elseif os(watchOS)
WindowGroup {
WatchOSHealthView()
}
#elseif os(macOS)
WindowGroup {
MacHealthDashboard()
}
#endif
}
}
关键实现技巧
共享业务逻辑:
- 使用
@StateObject在多个平台间共享相同的数据模型 - 通过
#if os()条件编译处理平台差异
- 使用
图表优化:
- 对 watchOS 使用简化版图表
- macOS 版本增加侧边栏导航
- iOS 版本采用 TabView 组织内容
性能考虑:
- 使用
task修饰符异步加载数据 - 对大数据集进行分页加载
- 使用
一致性设计:
- 保持跨平台的颜色主题一致
- 共享相同的图表组件但调整布局参数
最终效果
- iOS:完整的仪表盘体验,包含多个图表标签页
- watchOS:关键指标的简洁可视化
- macOS:带有导航侧边栏的专业数据分析视图
扩展练习
- 添加 HealthKit 集成获取真实健康数据
- 实现平台特定的图表交互方式(如 macOS 右键菜单)
- 增加 iCloud 同步功能
