Получение издателя от разных издателей в Объединении

#ios #swift #xcode #combine

Вопрос:

У меня есть свойство с фиксированным типом

 var statusPublisher: Published<Status>.Publisher
 

и некоторые другие статусы, такие как substatus1 , substatus2

и я хочу, чтобы он сочетал значения других статусов, таких как

 var statusPublisher: Published<Status>.Publisher {
    $substatus1.combineLatest($substatus2).map { s1, s2 -> Status in ... }
}
 

но там написано Cannot convert return expression of type 'Publishers.CombineLatest<Published<Substatus1>.Publisher, Published<Substatus2>.Publisher>' to return type 'Published<Status>.Publisher'

Мне удалось обойти это с помощью одного дополнительного

 var connectionStatusSubject = PassthroughSubject<Status, Never>()
 

что я вложил в

 var connectionStatusPublisher: AnyPublisher<Status, Never> {
    connectionStatusSubject.eraseToAnyPublisher()
}
 

с новым AnyPublisher здесь, но это кажется не таким аккуратным.

Есть ли какой-нибудь способ сделать это правильно?

Комментарии:

1. Проблема в том, что дженерики не являются ковариантными. Published<Status> , Published<Substatus1> , и Published<Substatus2> являются совершенно не связанными типами. Я бы предложил отказаться от идеи субстатуса (или объяснить, что вы на самом деле пытаетесь сделать, имея его).

Ответ №1:

Published<T>.Publisher это просто определенный тип издателя, созданный @Published оболочкой свойств. Нет никаких причин использовать это в качестве типа вычисляемого свойства.

Введите-стереть в AnyPublisher — как вы сделали с PassthroughSubject — за исключением того, что вам не нужен PassthroughSubject :

 var statusPublisher: AnyPublisher<Status, Never> {
    $substatus1
       .combineLatest($substatus2)
       .map { s1, s2 -> Status in ... }
       .eraseToAnyPublisher()
}