Swift Combine: What are those multicast functions for and how do I use them?

跟風遠走 提交于 2019-12-10 09:25:15

问题


Struggling with some combine problems I came across the "Working with Multiple Subscribers" section in https://developer.apple.com/documentation/combine/publisher :

func multicast<S>(() -> S) -> Publishers.Multicast<Self, S>

func multicast<S>(subject: S) -> Publishers.Multicast<Self, S>

However, when I tried to confirm my assumption that multicast would be needed when sending to multiple subscribers, I found out this is not necessary when trying on this playground code (modified from https://github.com/AvdLee/CombineSwiftPlayground/blob/master/Combine.playground/Pages/Combining%20Publishers.xcplaygroundpage/Contents.swift ) (run on 10.14.5 in Xcode Version 11.0 beta 3 (11M362v)):

enum FormError: Error { }

let usernamePublisher = PassthroughSubject<String, FormError>()
let passwordPublisher = PassthroughSubject<String, FormError>()

let validatedCredentials = Publishers.CombineLatest(usernamePublisher, passwordPublisher)
    .map { (username, password) -> (String, String) in
        return (username, password)
    }
    .map { (username, password) -> Bool in
        !username.isEmpty && !password.isEmpty && password.count > 12
    }
    .eraseToAnyPublisher()

let firstSubscriber = validatedCredentials.sink { (valid) in
    print("First Subscriber: CombineLatest: Are the credentials valid: \(valid)")
}

let secondSubscriber = validatedCredentials.sink { (valid) in
    print("Second Subscriber: CombineLatest: Are the credentials valid: \(valid)")
}

// Nothing will be printed yet as `CombineLatest` requires both publishers to have send at least one value.
usernamePublisher.send("avanderlee")
passwordPublisher.send("weakpass")
passwordPublisher.send("verystrongpassword")

This prints:

First Subscriber: CombineLatest: Are the credentials valid: false
Second Subscriber: CombineLatest: Are the credentials valid: false
First Subscriber: CombineLatest: Are the credentials valid: true
Second Subscriber: CombineLatest: Are the credentials valid: true

so it seems that no multicast is needed to address multiple subscribers. Or I am wrong?

So, what are those multicast functions for and how would I use them? Some example code would be nice.

Thanks,

Lars


回答1:


An answer/reference from the swift forums implies that the multicast methods are meant to build upon the .share() operator. From Philippe's post:

In that case it used to connect an upstream to a PassthroughSubject and then is auto connected. Normally when a Subscriber receives a Subscription it will cancel any additional Subscriptions past the first, Multicast gives an escape hatch to this behavior and handles multiple Subscriptions.

In practice, if you want to split a stream and multicast event updates through multiple pipelines in Combine, it seems the most pragmatic way is to create a @Published property, having any upstream pipeline update it with .assign() or within .sink(), and then set up additional pipelines with subscribers from the @Published property.



来源:https://stackoverflow.com/questions/56918286/swift-combine-what-are-those-multicast-functions-for-and-how-do-i-use-them

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!