我是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
个事件