Использование BehaviorRelay
- плохая идея, поскольку оно выдает значение, как только оно подписано. Это означает, что ваш NetworkingLayer
объект сделает запрос, как только будет создан.
Лучше было бы передать другой сигнал в метод init
:
init(provider: MoyaProvider<E>, request: Singal<E>, refresh: Signal<Void>)
Я не знаю, Мойя, но вот как бы я написал что-то подобное, используя URLSession:
enum RequestState<T> {
case loaded(T)
case error(Error)
case loading
}
class NetworkingLayer<T: Decodable> {
let response: Driver<RequestState<T>>
init(request: Signal<URLRequest>, refresh: Signal<Void>, provider: URLSession = URLSession.shared, decoder: JSONDecoder = JSONDecoder()) {
response = Observable.merge(request.asObservable(), refresh.withLatestFrom(request).asObservable())
.flatMapLatest { request in
provider.rx.data(request: request)
.map { try decoder.decode(T.self, from: $0) }
.map { RequestState.loaded($0) }
.startWith(.loading)
.catchError { Observable<RequestState<T>>.just(.error($0)) }
}
.share(replay: 1)
.asDriver(onErrorRecover: { fatalError($0.localizedDescription) })
}
}
Я добавил туда share(replay:)
, чтобы последующие подписчики не делали отдельные сетевые запросы, и я сделал декодер инъекционным, чтобы звонящий мог настроить его так, как он хочет.