如何使用ReactiveCocoa仅为每个下载的文件订阅多个选择器一次

时间:2015-01-27 13:40:55

标签: ios swift nsurlsession reactive-cocoa

我是ReactiveCocoa的新手并尝试使用它构建API客户端。我希望RAC观察者在每个URLSession:downloadTask:didFinishDownloadingToURL:委托回调中触发一次。因为我的代码现在它将为每个下载的文件创建一个观察者,并在每次下载文件时为所有以前的文件触发事件。每次下载文件时都会调用此方法。

使用RAC在每次完成时处理观察者的方法是正确的,还是使用RAC的不同部分而不是使用此模式的subscribeNext?

// In APIClient.swift

func urlSessionDownloadTask(method: httpMethod, url: String, acceptHeader: String, progress: NSProgress?, success: (url: NSURL) -> Void , failure: (error: APIError) -> ()) -> NSURLSessionTask? {
    let url = NSURL(string: url)
    var urlRequest = NSMutableURLRequest(URL: url!, cachePolicy: .ReturnCacheDataElseLoad, timeoutInterval: 50)
    urlRequest.HTTPMethod = method.rawValue
    urlRequest.allHTTPHeaderFields![Constants.HTTPHeaderKeys.accept] = acceptHeader

    RACSignalSubscriptionNext(selector: Selector("URLSession:downloadTask:didFinishDownloadingToURL:"), fromProtocol: NSURLSessionDownloadDelegate.self) { (racTuple) -> Void in
        let urlSession = racTuple.first as NSURLSession
        let downloadTask = racTuple.second as NSURLSessionDownloadTask
        let location = racTuple.third as NSURL
        println(location)
        println("Did finish downloading file, should only be called once per file")
        success(url: location)
    }
    RACSignalSubscriptionNext(selector:Selector("URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:") , fromProtocol: NSURLSessionDownloadDelegate.self) { (racTuple) -> Void in
        dispatch_async(dispatch_get_main_queue(), {
             let totalBytesWritten = racTuple.fourth as NSNumber
             if let actualProgress = progress {
                 actualProgress.completedUnitCount = totalBytesWritten.longLongValue
             }
        })

    }
    let task = session.downloadTaskWithRequest(urlRequest, completionHandler: nil)
    task.resume()
}

//  just a convenice method to setup a next subscription
func RACSignalSubscriptionNext(#selector:Selector, fromProtocol: Protocol, subscribeNext: (racTuple: RACTuple) -> Void) {
        rac_signalForSelector(selector, fromProtocol:fromProtocol).subscribeNext { (anyObject) -> Void in
            if let racTuple = anyObject as? RACTuple {
                subscribeNext(racTuple: racTuple)
            } else {
                println("something wrong happened")
            }
        }
    }

我没有使用完成处理程序downloadTaskWithRequest的原因是我想订阅多个URLsessionDownloadDelegate个事件

0 个答案:

没有答案