我的
currentTime
类中有以下计算属性 (Observable
),我想在 SwiftUI 视图中观察它。问题是属性的更改不会发布,因为它不依赖于存储的属性。我之前一直使用Combine
publishers来解决这个问题,但我想知道在iOS 17引入的新观察框架中是否有更好的方法来解决这个问题?
@available(iOS 17.0, *)
@Observable
class VideoPlayerVM {
private(set) public var player: AVPlayer = AVPlayer()
var currentTime:CMTime {
let time = self.player?.currentItem?.currentTime()
if time.isValid {
return time
}
return .invalid
}
}
无论您以前使用什么组合出版商也应该与
@Observable
一起使用。您只需 sink
该发布者并将其值分配给 @Observable
类中的存储属性。
也就是说,如果您想观察
AVPlayer
的当前时间,我不确定为什么您首先要使用组合发布器。有一个专门的方法,addPeriodicTimeObserver
,可以让你定期观察当前时间。
你可以这样使用它:
@Observable
@MainActor
class VideoPlayerVM {
private(set) public var player: AVPlayer = AVPlayer()
var currentTime: CMTime = .zero
private var observation: Any?
func startObservingCurrentTime() {
guard observation == nil else { return }
observation = player.addPeriodicTimeObserver(
forInterval: .init(
seconds: 0.5,
preferredTimescale: CMTimeScale(NSEC_PER_SEC)
),
queue: nil
) { time in
MainActor.assumeIsolated {
self.currentTime = time
}
}
}
func stopObservingCurrentTime() {
if let observation {
player.removeTimeObserver(observation)
observation = nil
}
}
}
您应该在拥有
stopObservingCurrentTime
的视图的 onDisappear
中调用 VideoPlayerVM
。
请注意,我在
MainActor.assumeIsolated
的闭包中使用了 addPeriodicTimeObserver
。这是安全的,因为 queue: nil
意味着闭包将在主调度队列上调用,主调度队列是主要参与者的串行执行器。