AFNetworking和下载二进制文件

时间:2012-10-29 23:01:12

标签: ios afnetworking

有没有人使用AFNetworking下载更大的文件有什么成功?这是我现在正在使用的代码:

NSFileManager *fm = [NSFileManager defaultManager];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dfwPath =  [documentsDirectory stringByAppendingPathComponent:@"sync_download.db"];

//Delete the existing one if our last sync was interrupted...
[fm removeItemAtPath:[documentsDirectory stringByAppendingPathComponent:@"sync_download.db"] error:nil];

NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
[parameters setObject:@"sync"   forKey:@"app"];
[parameters setObject:@"dl"     forKey:@"cmd"];
[parameters setObject:version   forKey:@"ver"];

[AFHTTPRequestOperation addAcceptableContentTypes:[NSSet setWithObject:@"application/bin"]];

AFMyClient *client = [AFMyClient sharedClient];

NSMutableURLRequest* rq = [client requestWithMethod:@"POST" path:@"myserver/ol.php" parameters:parameters];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:rq];

operation.outputStream = [NSOutputStream outputStreamToFileAtPath:dfwPath append:NO];

[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
    NSLog(@"The bytes download: %llu of %llu", totalBytesRead, totalBytesExpectedToRead);

    //float percentDone = ((float)((int)totalBytesRead) / (float)((int)totalBytesExpectedToRead));

}];

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

    NSLog(@"Finished downloading: %@", [operation responseString]);

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {

    NSLog(@"Error downloading: %@",[error debugDescription]);
}];

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation];

即使下载的数量大约为10MB,文件也会被创建,但它始终为零字节。永远不会达到“setDownloadProgressBlock”,但“setCompletionBlockWithSuccess”是。

以下是我在发送下载数据之前在服务器上设置标头的方法:

        $data = file_get_contents($filename);
        header('Pragma: public'); 
        header('Content-Type: application/bin');
        header('Content-Disposition: attachment; filename="'.basename($filename).'";');
        header('Content-Transfer-Encoding: binary');
        header('Content-Length: '.strlen($data));       
        echo $data;

使用较旧的ASIHttpRequest库,这非常有效。所以,如果有人知道发生了什么,我将非常感激。

2 个答案:

答案 0 :(得分:1)

三件事:

首先,您可能需要在runloop中安排输出流,以确保下载按预期工作。

其次,可能是您在该方法中创建的NSOperationQueue在操作完成之前被释放。相反,您应该将您的HTTP请求操作排入AFHTTPClient操作队列。

第三,无关:您应该使用AFHTTPClient -HTTPRequestOperationWithRequest:success:failure:而不是手动创建AFHTTPRequestOperation类,并执行setCompletionBlockWithSuccess:failure:。如果不使用客户端构造函数,则会错过已注册的操作逻辑和默认标头。

答案 1 :(得分:1)

好吧我明白了。事实证明我没有以最有效的方式从服务器发送数据,而且我也清理了我的HTTP Headers:

        $size = filesize($filename);
        header('Pragma: no-cache'); 
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="'.basename($filename).'";');
        header('Content-Transfer-Encoding: binary');
        header('Accept-Ranges: bytes');
        header('Cache-Control: max-age=604800');
        header("Content-Length: $size");        
        readfile($filename);
相关问题