MiddleКодЧастоЕщё не отвечали
Оберните одноразовый callback-API в Future, а поток delegate-колбэков — в publisher на основе subject
Соедините два не-Combine API с publisher'ами:
loadUser(completion: @escaping (Result<User, Error>) -> Void)срабатывает ровно один раз.LocationDelegateвызываетdidUpdate(_ location: Location)много раз.
Требования:
и отдайте его как publisher только для чтения.
- Оберните
loadUserвFuture<User, Error>. - Обеспечьте поток delegate через
PassthroughSubject, куда шлёт delegate,
func userPublisher() -> AnyPublisher<User, Error> {
// ваш код здесь — оберните loadUser в Future
}
final class LocationStream {
// ваш код здесь — PassthroughSubject + открытый publisher + хук delegate
}
Допишите реализацию.
Для одноразового вызова — Future: выполните loadUser и передайте Result в promise; срабатывает раз, кэшируя результат. Для delegate держите приватный PassthroughSubject, шлите в него из колбэков и отдавайте eraseToAnyPublisher() для чтения.
- ✗Берут
Futureдля многозначного потока delegate - ✗Открывают
PassthroughSubjectвместо стёртого publisher только для чтения - ✗Ждут, что
Futureзаново запустит замыкание на каждой подписке
- →Почему
Futureкэширует и переотдаёт свой единственный результат? - →Как обеспечить поток delegate через
CurrentValueSubject?
func userPublisher() -> AnyPublisher<User, Error> {
Future { promise in
loadUser { result in promise(result) }
}
.eraseToAnyPublisher()
}
final class LocationStream {
private let subject = PassthroughSubject<Location, Never>()
var locations: AnyPublisher<Location, Never> { subject.eraseToAnyPublisher() }
func didUpdate(_ location: Location) {
subject.send(location)
}
}
A Future calls its promise once and caches that single result, replaying it to any subscriber. A PassthroughSubject turns an open-ended delegate callback into a stream: each didUpdate becomes subject.send, and callers subscribe to the erased publisher without being able to send into it.