Swift 合并自定义发布者:存储对订阅者数组的引用?

Swift Combine custom Publisher: Storing a reference to an array of Subscribers?

我正在尝试编写一个自定义 Combine Publisher,它将从 AVAudioEngine 抽头发送分贝和时间戳。在浏览了大量教程和 WWDC 视频后,我 仍然 找不到 Publisher 如何跟踪已订阅的 Subscriber 的示例它。

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
    }
}

我假设 AudioVolumePublisher 应该存储其活跃订阅者的列表,但是添加 属性 比如

var subscribers = [S]()

无法编译,因为 Subscriber 具有关联类型。这甚至是处理 Subscriber 的正确方法吗?如果是这样,存储它们的最佳方法是什么?类型擦除是我唯一实用的选择吗?

您也许可以通过 CurrentValueSubject or PassthroughSubject 来实现您的目标。

假设这是您要发送的形状:

struct AudioVolume {
  let decimal: Decimal
  let timestamp: TimeStamp
}

实例化主题

let audioPublisher = PassthroughSubject<AudioVolume, Never>()

每当您需要发布新值时:

let audioVolume = AudioVolume(....)
audioPublisher.send(audioVolume)

每当您需要订阅发布者时:

audioPublisher
  .sink { audioVolume in
    // do something with audioVolume
  }
  .store(in: &cancellables) // retain the subscription in cancellables as long as you want to remain subscribed