2016-08-17 44 views
3

在爲我的網絡層創建反應式擴展時,我注意到了一些模式,我只想簡單介紹一下我的邏輯以便將來實現......所以我現在所擁有的是幾個方法類同這一個:在網絡周圍創建反應包裝

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和我的當前包裝時,我有點卡住了。到目前爲止,我喜歡的東西結束:

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再次...

任何建議什麼是正確的方法?我至少在什麼地方?或者我完全錯誤的方向?

回答

0

有東西...至少我想我有東西。它很有效,現在我對這個解決方案感到滿意,所以讓我們跳到結論。

.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) 
      } 
    } 
} 

在我看來,這看起來有點清潔☺️