NSURLConnection可用于实时计算md5:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
// theData is a small piece
NSURLSessionDownloadTask是NSURLConnection的“升级”。但是如何在下载之后再检查md5而不再读取整个文件?它的界面如下:
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request
completionHandler:
^(NSURL *location, NSURLResponse *response, NSError *error) {
// the whole file is downloaded and saved at location.
}];
这里的关键要求是内存占用量低,文件必须完全下载。
答案 0 :(得分:2)
如果您希望数据到达小的NSData片段,您可以检查并逐渐附加到更大的NSMutableData,就像使用connection:didReceiveData:
一样,请求data task而不是下载任务。
您致电dataTaskWithRequest:
,提供代表,并启动数据任务(使用resume
) - 代表接收URLSession:dataTask:didReceiveData:
,与旧的NSURLConnection日期完全相同。
这是一个完整的工作示例(除非我不会告诉您在数据到达时如何处理数据):
- (NSURLSession*) configureSession {
NSURLSessionConfiguration* config =
[NSURLSessionConfiguration ephemeralSessionConfiguration];
config.allowsCellularAccess = NO;
NSURLSession* session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
return session;
}
- (IBAction) doHTTP: (id) sender {
if (!self.session)
self.session = [self configureSession];
NSString* s = // some URL string
NSURL* url = [NSURL URLWithString:s];
NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:url];
NSURLSessionDataTask* task = [[self session] dataTaskWithRequest:req];
self.task = task;
[task resume];
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
NSLog(@"received %lu bytes of data", (unsigned long)data.length);
// do something with the data here!
}
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
NSLog(@"completed; error: %@", error);
}
答案 1 :(得分:1)
正如Matt所说,您可以使用数据任务,这样您就可以在下载数据时轻松查看数据。
但是,如果您想观察下载任务,如果您愿意承担一些小风险,则可以完成类似的事情。
我确定我会为以下内容获得一百万张选票,但请记住......当你需要一把螺丝刀,而你所拥有的只是一把锤子时,你将锤子翻过来,把它当作螺丝刀使用......或者用螺丝钉敲击它以致它变成钉子......
首先,我认为API已被破坏。代表们应该提供这两件事中的至少一件。如果您同意,请提交雷达。代理人应该提供临时文件(更不用说首选 - 我认为它应该保持不透明),或者它应该提供NSData
中写的URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:
- 这是正确答案。
无论如何,如果您愿意使用无证件,非官方方法......
临时文件存储在Library/Caches/com.apple.nsnetworkd/
中,因此您可以轻松查看并确定哪些文件用作临时目标。
或者,您可以再次非正式,通过使用cancelByProducingResumeData:
取消下载然后取消归档恢复数据blob来确定临时文件 - 恢复数据blob当前是归档字典 - 并从字典中获取文件路径。然后,您可以恢复下载,知道正在使用哪个临时文件进行下载。
无论如何,一旦你有了这个文件,你可以在URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:
里面只读取文件中最近写的块。
现在,说到这里,您可能只想使用数据任务,因为它会正式为您提供刚下载的数据...但您可以诉诸此hack获取下载到文件的数据,如果你必须进行后台下载 - 必须关闭下载任务。
您可能遇到的一个问题是文件IO可能是缓冲的,因此实际刷新的内容(可从单独的文件描述符中获取)可能与委托方法中报告的内容不同。您可能只需要跟踪您读取的最后一个字节,并在该代理中,只需从那里读取到文件的当前末尾...
您的里程肯定会有所不同,但它会让您在写入文件时访问数据。
您必须为URLSession:downloadTask:didFinishDownloadingToURL:
做同样的事情才能获得最终的数据。