我正在创建一个网络层,在其中注入API提供程序并将事件调用给initialize方法。
class NetworkingLayer<T: Decodable, E: TargetType> {
var response: Driver<T>
init(provider: MoyaProvider<E>, request: Singal<E>) {
let requestState = request
.flatMapLatest({
provider.rx.request($0).map(Respose<T>.self)
.map { ReqestState.loaded($0) }
.asDriver(onErrorRecover: { error in
return Driver.just(.error(error))
})
.startWith(.loading)
})
.asDriver(onErrorRecover: { fatalError($0.localizedDescription) })
response = requestState
.map({ $0.data?.data })
.filterNil()
}
}
通过以下方式使用它们:
class ViewModel {
let networking: DataNetworkingResponse<[TagItem], ScoutEnpoint>
init(provider: MoyaProvider<Endpoint>, event: Singal<[Int]>) {
let request = event
.map({ Endpoint.getNewItems(prevItemsIds: $0) })
self.networking = NetworkingLayer(provider: provider, request: request)
}
}
所有工作都像魅力。但是现在我必须实现刷新功能。刷新我的上一个请求。我已将此let refresh: Signal<()> = Signal.empty()
属性添加到我的网络层。但是不知道如何保存我的上一个请求。
class NetworkingLayer<T: Decodable, E: TargetType> {
let refresh: BehaviorRelay<()> = BehaviorRelay.init(value: ())
...
}
如何实现这样的刷新?
viewModel.networking.refresh.accept(())
答案 0 :(得分:0)
使用BehaviorRelay
是一个坏主意,因为它在订阅后会立即发出一个值。这意味着您的NetworkingLayer
对象将在构造后立即发出请求。
更好的方法是将另一个Signal传递到init
方法中:
init(provider: MoyaProvider<E>, request: Singal<E>, refresh: Signal<Void>)
我不了解Moya,但是这就是我使用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:)
放在那儿,这样以后的订户就不会发出单独的网络请求,并且我使解码器可注入,以便调用者可以根据需要配置它。