[英]How to use Combine's CurrentValueSubject and access it in a SwiftUI View?
My understanding is a CurrentValueSubject publisher in Combine is good for accessing on demand, as opposed to a regular Publisher that emits a value once.我的理解是,Combine 中的 CurrentValueSubject 发布者适合按需访问,而不是发出一次值的常规发布者。 So I'm trying to use one here in an Environment Object to store the total energy burned in an HKWorkout so that I can access it after the workout is finished in a SwiftUI View.
因此,我尝试在 Object 环境中使用一个来存储 HKWorkout 中燃烧的总能量,以便在锻炼完成后在 SwiftUI 视图中访问它。 With the code below I get the compiler error
Cannot convert return expression of type 'AnyCancellable' to return type 'Double'
so I think I need to do some type of casting but can't figure it out?使用下面的代码,我得到编译器错误
Cannot convert return expression of type 'AnyCancellable' to return type 'Double'
所以我认为我需要进行某种类型的转换但无法弄清楚?
class WorkoutManager: NSObject, HKWorkoutSessionDelegate, HKLiveWorkoutBuilderDelegate, ObservableObject {
var finishedWorkoutTotalEnergyBurned = CurrentValueSubject<Double, Never>(0.0)
func stopWorkout() {
self.finishedWorkoutTotalEnergyBurned.value = unwrappedWorkout.totalEnergyBurned!.doubleValue(for: .kilocalorie())
}
}
struct SummaryView: View {
@StateObject var workoutManager = WorkoutManager()
var body: some View {
Text("\(getFinishedWorkoutTotalEnergyBurned())")
.navigationBarHidden(true)
//.navigationTitle("Workout Complete")
}
func getFinishedWorkoutTotalEnergyBurned() -> Double {
workoutManager.finishedWorkoutTotalEnergyBurned.sink(receiveValue: { $0 })
}
}
I think your question shows that you need to learn a bit more the foundational principle behind SwiftUI, and behind Combine (that statement about "CurrentValueSubject vs regular Publisher" was quite wrong).我认为您的问题表明您需要更多地了解 SwiftUI 和 Combine 背后的基本原理(关于“CurrentValueSubject vs regular Publisher”的说法是完全错误的)。
All you need here is to expose a @Published
property on your WorkoutManager
, and set it to the value that you want, when needed:您需要在
WorkoutManager
上公开一个@Published
属性,并在需要时将其设置为您想要的值:
class WorkoutManager: NSObject, HKWorkoutSessionDelegate, HKLiveWorkoutBuilderDelegate, ObservableObject {
@Published var finishedWorkoutTotalEnergyBurned = 0.0
func stopWorkout() {
finishedWorkoutTotalEnergyBurned = unwrappedWorkout.totalEnergyBurned!.doubleValue(for: .kilocalorie())
}
}
struct SummaryView: View {
@StateObject var workoutManager = WorkoutManager()
var body: some View {
Text("\(workoutManager.finishedWorkoutTotalEnergyBurned)")
.navigationBarHidden(true)
}
}
@Published
does use a Combine publisher under the hood, which in combination with @StateObject
cause the view to update. @Published
确实在后台使用了 Combine 发布者,它与@StateObject
结合使用会导致视图更新。 But all you need to reason about here, is how and when to set these properties - and the view will update automatically.但是您需要在这里推理的是如何以及何时设置这些属性 - 并且视图将自动更新。 In the case you showed, there's likely no need to use a publisher directly.
在您展示的情况下,可能不需要直接使用发布者。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.