我正在尝试编写一个自定义组合Publisher,它将从AVAudioEngine水龙头发送分贝和时间戳。在浏览了大量教程和 WWDC 视频之后,我仍然找不到如何Publisher跟踪Subscriber已订阅它的 s 的示例。
public typealias AudioVolume = Double
public struct AudioVolumePublisher: Publisher {
public typealias Output = AudioVolume
public typealias Failure = Error
}
public class AudioVolumeSubscription<S: Subscriber>: NSObject, Subscription {
private var subscriber: S?
public var combineIdentifier = CombineIdentifier()
public init(for subscriber: S) {
self.subscriber = subscriber
}
public func request(_ demand: Subscribers.Demand) {
...
}
public func cancel() {
subscriber = nil
}
}
Run Code Online (Sandbox Code Playgroud)
我假设AudioVolumePublisher应该存储其活跃订阅者的列表,但添加一个属性,例如
var subscribers = [S]()
Run Code Online (Sandbox Code Playgroud)
不会编译,因为Subscriber有关联的类型。这是否是处理 s 的正确方法Subscriber?如果是,那么存储它们的最佳方法是什么?类型擦除是我唯一实用的选择吗?
您可以通过 或 来实现您的CurrentValueSubject目标PassthroughSubject。
假设这是您要发送的形状:
struct AudioVolume {
let decimal: Decimal
let timestamp: TimeStamp
}
Run Code Online (Sandbox Code Playgroud)
实例化主题
let audioPublisher = PassthroughSubject<AudioVolume, Never>()
Run Code Online (Sandbox Code Playgroud)
每当您需要发布新值时:
let audioVolume = AudioVolume(....)
audioPublisher.send(audioVolume)
Run Code Online (Sandbox Code Playgroud)
每当您需要订阅发布者时:
audioPublisher
.sink { audioVolume in
// do something with audioVolume
}
.store(in: &cancellables) // retain the subscription in cancellables as long as you want to remain subscribed
Run Code Online (Sandbox Code Playgroud)