使用 Combine 的发布者和订阅者发布实时 HealthKit 数据?
Using Combine's Publishers and Subscribers to publish real time HealthKit data?
我一直在 UIKit 和 WatchKit 中使用委托来在对象之间进行通信,例如传递数据。一个 WorkoutManager ViewModel,它在 HKworkout 期间接收来自 HealthKit 的委托回调,将卡路里、心率传递给 InterfaceController。
我现在正在尝试使用 Combine 和 SwiftUI 来传递相同的数据,但我有点不知所措。我使用 WorkoutManager class 作为我在 ContentView 中初始化的环境对象:
class WorkoutManager: NSObject, HKWorkoutSessionDelegate, HKLiveWorkoutBuilderDelegate, ObservableObject {
@Published var totalEnergyBurned: Double = 0
//How to subscribe to the changes?
//Omitted HealthKit code that queries and pushes data into totalEnergyBurned here
}
struct ContentView: View {
let healthStore = HKHealthStore()
@StateObject var workoutManager = WorkoutManager()
var sessionTypes = [SessionType.Game, SessionType.Practice, SessionType.Pickup]
var body: some View {
List {
ForEach(sessionTypes) { sessionType in
NavigationLink(destination: LiveWorkoutView(sessionType: sessionType)) {
SessionTypeRow(name: sessionType.stringValue)
}
}
}
.navigationTitle("Let's Go!")
.onAppear {
let authorizationStatus = healthStore.authorizationStatus(for: HKSampleType.workoutType())
switch authorizationStatus {
case .sharingAuthorized:
print("sharing authorized")
case .notDetermined:
print("not determined")
HealthKitAuthManager.authorizeHealthKit()
case .sharingDenied:
print("sharing denied")
HealthKitAuthManager.authorizeHealthKit()
default:
print("default in healthStore.authorizationStatus in ContentView")
HealthKitAuthManager.authorizeHealthKit()
}
}
}
}
我的目标是将更改发布到 ContentView 的所有子项,但我不确定如何订阅更改?
import SwiftUI
struct LiveWorkoutView: View {
@State var sessionType: SessionType
@StateObject var workoutManager = WorkoutManager()
var body: some View {
VStack {
Text("\(workoutManager.totalEnergyBurned)")
Button(action: {
workoutManager.stopWorkout()
}) {
Text("End Workout")
}
}
.onAppear {
workoutManager.startWorkout()
workoutManager.sessionType = sessionType
}
.navigationTitle(sessionType.stringValue)
}
}
//How to subscribe to the changes?
你不知道。 @StateObject
在视图中注入订阅者,因此只需在视图 body
中的某处(需要的地方)使用 workoutManager. totalEnergyBurned
属性 并且一旦此 属性 更改,视图将自动刷新(例如,您从 HealthKit 回调中为其分配新值。
我一直在 UIKit 和 WatchKit 中使用委托来在对象之间进行通信,例如传递数据。一个 WorkoutManager ViewModel,它在 HKworkout 期间接收来自 HealthKit 的委托回调,将卡路里、心率传递给 InterfaceController。
我现在正在尝试使用 Combine 和 SwiftUI 来传递相同的数据,但我有点不知所措。我使用 WorkoutManager class 作为我在 ContentView 中初始化的环境对象:
class WorkoutManager: NSObject, HKWorkoutSessionDelegate, HKLiveWorkoutBuilderDelegate, ObservableObject {
@Published var totalEnergyBurned: Double = 0
//How to subscribe to the changes?
//Omitted HealthKit code that queries and pushes data into totalEnergyBurned here
}
struct ContentView: View {
let healthStore = HKHealthStore()
@StateObject var workoutManager = WorkoutManager()
var sessionTypes = [SessionType.Game, SessionType.Practice, SessionType.Pickup]
var body: some View {
List {
ForEach(sessionTypes) { sessionType in
NavigationLink(destination: LiveWorkoutView(sessionType: sessionType)) {
SessionTypeRow(name: sessionType.stringValue)
}
}
}
.navigationTitle("Let's Go!")
.onAppear {
let authorizationStatus = healthStore.authorizationStatus(for: HKSampleType.workoutType())
switch authorizationStatus {
case .sharingAuthorized:
print("sharing authorized")
case .notDetermined:
print("not determined")
HealthKitAuthManager.authorizeHealthKit()
case .sharingDenied:
print("sharing denied")
HealthKitAuthManager.authorizeHealthKit()
default:
print("default in healthStore.authorizationStatus in ContentView")
HealthKitAuthManager.authorizeHealthKit()
}
}
}
}
我的目标是将更改发布到 ContentView 的所有子项,但我不确定如何订阅更改?
import SwiftUI
struct LiveWorkoutView: View {
@State var sessionType: SessionType
@StateObject var workoutManager = WorkoutManager()
var body: some View {
VStack {
Text("\(workoutManager.totalEnergyBurned)")
Button(action: {
workoutManager.stopWorkout()
}) {
Text("End Workout")
}
}
.onAppear {
workoutManager.startWorkout()
workoutManager.sessionType = sessionType
}
.navigationTitle(sessionType.stringValue)
}
}
//How to subscribe to the changes?
你不知道。 @StateObject
在视图中注入订阅者,因此只需在视图 body
中的某处(需要的地方)使用 workoutManager. totalEnergyBurned
属性 并且一旦此 属性 更改,视图将自动刷新(例如,您从 HealthKit 回调中为其分配新值。