2

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 であっても常に 0 バイトです。「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 ライブラリを使用すると、これは完全に機能しました。だから、誰かが何が起こっているのか考えているなら、私はとても感謝しています.

4

2 に答える 2

1

三つのこと:

まず、ダウンロードが意図したとおりに機能するように、実行ループで出力ストリームをスケジュールする必要がある場合があります。

次に、NSOperationQueueそのメソッドで作成しているものが、操作が終了する前に割り当てが解除されている可能性があります。代わりに、HTTPリクエスト操作をAFHTTPClient操作キューにエンキューする必要があります。

第三に、無関係です。手動でクラスAFHTTPClient -HTTPRequestOperationWithRequest:success:failure:を作成して実行する代わりに、を使用する必要があります。クライアントコンストラクターを使用しないと、登録済みの操作ロジックとデフォルトのヘッダーを見逃してしまいます。AFHTTPRequestOperationsetCompletionBlockWithSuccess:failure:

于 2012-10-30T06:34:21.173 に答える
1

わかりました。サーバーから最も効率的な方法でデータを送信していなかったことが判明し、次のように HTTP ヘッダーをクリーンアップしました。

        $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);
于 2012-10-30T15:25:56.720 に答える