创建像RxSwift的Observable之类的Combine的发布者。为Alamofire请求创建

问题描述 投票:0回答:1

我使用下面的代码来生成冷的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
}

其中Mappable是基于ObjectMapper的类型,self.session是Alamofire的Session对象。

我在Apple的Observable.create {...}框架中找不到与Combine等效的文件。我唯一发现的是URLSession.shared.dataTaskPublisher(for:),它使用Apple的URLSession类创建了一个发布者。

如何将以上可观察的观测值转换为Alamofire联合收割机的发布者?

ios swift alamofire rx-swift combine
1个回答
0
投票
您可以使用FutureFuture的回调连接到组合responseObject。我没有Alamofire可以方便地进行测试,但是我认为以下方法可以工作:

Publisher

注意,这比RxSwift版本要简单一些,因为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()
}
直接获取promise,因此我们不必切换Result

A response.result有点“冷淡”的发行商。这就像一个可观察到的热点,因为它可以立即执行其主体并且仅执行一次,因此可以立即启动Alamofire请求。这也就像冷的可观察到的,因为每个订阅者最终都会收到一个值或一个错误(假设您最终会调用Future)。 promise仅执行一次其主体,但会缓存您传递给FutureResult

您可以通过将promise包装在Future中来创建真正的冷发行商:

Deferred

每次订阅时,
Deferred都会调用其主体来创建一个新的内部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()
}
。因此,每次订阅时,您都将创建一个新的Deferred,它将立即启动新的Alamofire请求。如果要使用Publisher运算符,例如Future,这将很有用。
© www.soinside.com 2019 - 2024. All rights reserved.