swift - 围绕网络创建响应式(Reactive)包装器

标签 swift alamofire reactive-programming rx-swift reactivex

在为我的网络层创建响应式扩展时,我注意到一些模式,我想提取这些模式只是为了简化我 future 实现的逻辑......所以我现在拥有的是一些与此类似的方法:

static func create(params: [ String: AnyObject ]) -> Observable<Type> {
    return Observable<Type>.create { observer -> Disposable in
        let request = Alamofire.request(TypeAPI.Create(params: params).responseJSON { response in
            switch response.result {
            case .Success(let value):
                guard response.response?.statusCode != 409 else {
                    observer.onError(RequestError.TypeAlreadyExists)
                    return
                }

                guard let dict = value as? [ String: AnyObject ] else {
                    observer.onError(RequestError.ParsingError)
                    return
                }

                guard let parsedType: Type = try? Unbox(dict) else {
                    observer.onError(RequestError.MappingError)
                    return
                }

                observer.onNext(parsedType)
            case .Failure(let error):
                observer.onError(RequestError.convert(error))
            }
        }

        return AnonymousDisposable {
            request.cancel()
        }
    }
}

例如AnonymousDisposable事情总是在重复。 我看过 RxAlamofire实现及其 rx_request method基本上遵循非常熟悉的模式,但是当我尝试实际使用时我有点卡住了 RxAlamofire用我现在的 wrapper 。到目前为止,我已经结束了类似的事情:

static func rx_create(params: [ String: AnyObject ]) -> Observable<Type> {
    let manager: Manager = Manager.sharedInstance
    manager.rx_request { manager -> Request in
        return Alamofire.request(TypeAPI.Create(params: params))
    }
}

但是rx_request返回 Observable<Request>我需要 Observable<Type> .如果我去添加 .flatMap比我用 AnonymousDisposable 结束再次……

有什么建议是正确的方法吗?我至少在附近的某个地方吗?还是我的方向完全错了?

最佳答案

得到了一些东西...至少我想我得到了一些东西。它有效,目前我对这个解决方案很满意,所以让我们直接下结论吧。

使用 .flatMap 的路径是正确的,但为了避免额外的 Observable.create 我不得不深入研究 RxAlamofire 并从中受益不错的 rx_responseJSON 方法👌

但后来我意识到我可以走得更远并提取这个过程,所以我已经完成了所有请求包装类通用的通用方法,如下所示:

static func rx_request<T>(requestConvertible: URLRequestConvertible, completion: (Request) -> Observable<T> ) -> Observable<T> {
    let manager: Manager = Manager.sharedInstance
    return manager
        .rx_request { manager -> Request in
            return Alamofire.request(requestConvertible)
        }
        .flatMap { request -> Observable<T> in
            return completion(request)
        }
        .shareReplay(1)
}

现在我可以像这里一样使用这个方法了:

static func rx_create(options: String) -> Observable<Type> {
    return rx_request(TypesAPI.Create(options: options)) { request -> Observable<Type> in
        request
            .validate()
            .rx_responseJSON()
            .flatMap{ (request, json) -> Observable<Type> in
                guard
                    let dict = json as? [ String: AnyObject ],
                    let parsedType: Type = try? Unbox(dict) else {
                        return Observable.error(RequestError.ParsingError)
                }

                return Observable.just(parsedType)
            }
    }
}

在我看来这看起来更干净了☺️

关于swift - 围绕网络创建响应式(Reactive)包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39005943/

相关文章:

ios - 在 SwiftUI/Swift/Objective-C/Xamarin 中将底部边框线添加到 UI TextField View

swift - 未调用完成处理程序 - Alamofire/stripe

ios - 从 Alamofire 闭包返回一个值

swift - Swift 2.2 中 Alamofire 请求的返回值

ios - 处理可观察序列 RxSwift 上的循环样式事件

ios - iOS 应用程序的设置

swift - 用户定义的 SWIFT_WHOLE_MODULE_OPTIMIZATION 和 Swift 优化级别之间有什么区别?

c# - 具有大对象的响应式(Reactive)扩展 SelectMany

javascript - 在半页中 react 路由器导航

swift - xcode7 上出现错误。 view.layer.renderInContext(上下文!)