结合Alamofire和RxSwift

时间:2015-12-07 13:08:38

标签: ios swift mvvm rx-swift

我有#!/bin/bash if [ -z "$1" ]; then echo "ivalid argument" exit 1; fi; cnt=1; while read line; do echo "$cnt $line"; ((cnt++)); done<"$1"; 的自定义实现:

Alamofire

我想将MVVM和RxSwift应用到我的项目中。但是,我找不到合适的方法来做到这一点。

我想要实现的是protocol HTTPProtocol: class { typealias RequestType typealias RespondType func doRequest(requestData: RequestType) -> Self func completionHandler(block:(Result<RespondType, NSError>) -> Void) -> Self } //example of a request: locationInfo //Make a request .doRequest(HTTPLocationInfo.RequestType(coordinate: $0)) //Call back when request finished .completionHandler { result in switch result { case .Success(let info): self.locationInfoRequestSuccess(info) case .Failure(let error): self.locationInfoRequestFailed(error) } } ViewModel可以做这些事情:

ViewController

非常感谢任何帮助。谢谢。

2 个答案:

答案 0 :(得分:4)

你可以使用RxAlamofire作为@Gus在评论中说。但是,如果您使用的是默认情况下不支持Rx扩展的任何库,您可能需要手动进行转换。

因此,对于上面的代码片段,您可以从已实现的回调处理程序创建一个observable

    func getResultsObservable() -> Observable<Result> {
        return Observable.create{ (observer) -> Disposable in
            locationInfo
                //Make a request
                .doRequest( .... )

                //Call back when request finished
                .completionHandler { result in
                    switch result {
                    case .Success(let info): observer.on(Event.Next(info))
                    case .Failure(let error): observer.on(Event.Error(NetworkError()))
                    }
            }       
            return Disposables.create {
               // You can do some cleaning here      
            }
        }
    }

回调处理程序是对observer模式的实现,因此将其映射到自定义Observable是一个简单的操作。

一个好的做法是在处理时取消网络请求,例如这是一个完整的一次性Post请求:

return Observable<Result>.create { (observer) -> Disposable in
        let requestReference = Alamofire.request("request url",
            method: .post,
            parameters: ["par1" : val1, "par2" : val2])
            .validate()
            .responseJSON { (response) in
                switch response.result{
                case .success:
                     observer.onNext(response.map{...})
                     observer.onCompleted()
                case .failure:
                    observer.onError(NetworkError(message: response.error!.localizedDescription))
                }
        }
        return Disposables.create(with: {
            requestReference.cancel()
        })

注意:在快速3 Disposables.create()替换为NopDisposable.instance

之前

答案 1 :(得分:0)

您似乎不需要订阅newCoordinate,因此我只是将其作为请求func

然后,使用您从Alamofire返回的信息,只需在locationInfoResult上设置值,您就会在ViewController

中获得新结果
class ViewController: UIViewController {
    func viewDidLoad() {
        super.viewDidLoad()

        //subscribe to info changes
        viewModel.locationInfoResult
            .subscribeNext { info in 
                //do something with info...
            }
    }

    func googleMapDelegate(mapMoveToCoordinate: CLLocationCoordinate2D) {
        viewModel.requestLocationInfo(mapMoveToCoordinate)
    }
}

class ViewModel {
    let locationInfoResult: Variable<LocationInfoResult?>(nil)

    init() {
    }

    func requestLocationInfo(location: CLLocationCoordinate2D) {
        //do Alamofire stuff to get info

        //update with the result
        locationInfoResult.value = //value from Alamofire
    }
}