Ios 创建联合收割机';像RxSwift';s可观察。为Alamofire请求创建
我使用下面的代码生成一个coldIos 创建联合收割机';像RxSwift';s可观察。为Alamofire请求创建,ios,swift,alamofire,rx-swift,combine,Ios,Swift,Alamofire,Rx Swift,Combine,我使用下面的代码生成一个coldRxSwift Observable: func doRequest<T :Mappable>(request:URLRequestConvertible) -> Observable<T> { let observable = Observable<T>.create { [weak self] observer in guard let self = self else { return
RxSwift Observable
:
func doRequest<T :Mappable>(request:URLRequestConvertible) -> Observable<T> {
let observable = Observable<T>.create { [weak self] observer in
guard let self = self else { return Disposables.create() }
self.session.request(request).validate().responseObject { (response: AFDataResponse<T>) in
switch response.result {
case .success(let obj):
observer.onNext(obj)
observer.onCompleted()
case .failure(let error):
let theError = error as Error
observer.onError(theError)
}
}
return Disposables.create()
}
return observable
}
EDIT2:我必须删除专用队列,因为它不需要,Alamofire自己解析解码,所以删除队列及其用法(.receive(on:self.apiQueue)
)您可以使用它将响应对象的回调连接到联合发布服务器。我没有Alamofire可供测试使用,但我认为以下方法应该有效:
func doRequest<T: Mappable>(request: URLRequestConvertible) -> AnyPublisher<T, AFError> {
return Future { promise in
self.session
.request(request)
.validate()
.responseObject { (response: AFDataResponse<T>) in
promise(response.result)
}
}.eraseToAnyPublisher()
}
Deferred
每次订阅时都会调用它的主体来创建一个新的内部Publisher
。因此,每次订阅时,您都将创建一个新的Future
,它将立即启动一个新的Alamofire请求。如果您想使用重试
操作符,如中所示,这将非常有用。我在问题中添加了一个编辑。您需要更多帮助吗?在您的编辑中,我看不到任何需要更多帮助的请求。是的,我对呼叫receive(on:)
接线员的位置持怀疑态度,我认为最好将其放置在未来的
之后,而不是在延迟的
之后。在您拥有它的地方就可以了,但我不知道为什么需要发送到私有队列。摘自Ray Wenderlich的合并书第248页:“…要在后台线程上解析JSON并保持应用程序的其余部分响应,让我们创建一个新的自定义发送队列…”,然后作者创建了我在问题中列出的队列。用法如本书所列:URLSession.shared.dataTaskPublisher(for:url).receive(on:apiQueue).map(\.data).decode(type:MyModel.self,decoder:decoder).catch{in Empty()}.eraseToAnyPublisher()
注意,Alamofire已经在后台队列中执行响应处理,由于在主队列上调用了完成处理程序(只完成未来的
),因此您可能不需要接收(on:)
调用。
func doRequest<T: Mappable>(request: URLRequestConvertible) -> AnyPublisher<T, AFError> {
return Future { promise in
self.session
.request(request)
.validate()
.responseObject { (response: AFDataResponse<T>) in
promise(response.result)
}
}.eraseToAnyPublisher()
}
func doRequest<T: Mappable>(request: URLRequestConvertible) -> AnyPublisher<T, AFError> {
return Deferred {
Future { promise in
self.session
.request(request)
.validate()
.responseObject { (response: AFDataResponse<T>) in
promise(response.result) }
}
}.eraseToAnyPublisher()
}