私は iOS から始めており、webview を使用して単純なファイル ダウンローダーをコーディングしようとしています。
複数のファイルをダウンロードする必要がありますが、同時に呼び出されることはありません (私が見た例のように)。それは、デスクトップ ブラウザーと同じようにすべきです: すべてのダウンロードを連続して行うのではなく、ブラウジング中にいつでも新しい操作を追加できるべきです...
読んで読んだ後、afnetworkingを発見し、実装しようとしても良い結果が得られませんでした... 複数の操作を管理する方法がわからないためです!
私の質問は、多くの操作を追加したら、それらを個別に呼び出すにはどうすればよいですか? たとえば、そのうちの 1 つだけを停止またはキャンセルします。
これはコードです:
...
AFHTTPClient *httpClient;
...
- (void)DownloadFileFromUrl:(NSString *)fileURL{
NSURL *url = [NSURL URLWithString:fileURL];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//I've tried to init httpClient here each time, or at didLoad with a nil baseurl
httpClient =[[AFHTTPClient alloc]initWithBaseURL: [NSURL URLWithString:@"fileURL"]];
[httpClient.operationQueue setMaxConcurrentOperationCount:10];
AFDownloadRequestOperation *operation = [[AFDownloadRequestOperation alloc] initWithRequest:request
targetPath:targetPath
shouldResume:YES];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
//COOL!
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//failure case
//remove the file if saved a part of it!
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:targetPath error:&error];
if (error) {
//ERROR
}
if ([operation isCancelled]) {
}
}];
[operation setProgressiveDownloadProgressBlock:^(AFDownloadRequestOperation *operation1, NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpected, long long totalBytesReadForFile, long long totalBytesExpectedToReadForFile)
{
if (totalBytesExpectedToReadForFile > 0) {
dispatch_async(dispatch_get_main_queue(), ^{
//NSLog(@"Operation%i: bytesRead: %d", 1, bytesRead);
//NSLog(@"Operation%i: totalBytesRead: %lld", 1, totalBytesRead);
//NSLog(@"Operation%i: totalBytesExpected: %lld", 1, totalBytesExpected);
//NSLog(@"Operation%i: totalBytesReadForFile: %lld", 1, totalBytesReadForFile);
//NSLog(@"Operation%i: totalBytesExpectedToReadForFile: %lld", 1, totalBytesExpectedToReadForFile);
});
}
}];
[httpClient.operationQueue addOperation:operation];
//OR ?[httpClient enqueueHTTPRequestOperation:operation];
}
ファイルを 1 つだけダウンロードすると、httpClient.operationQueue.operations[0] を呼び出すため、すべて問題ないように見えます... そのデータを取得し、どこからでも [[httpClient.operationQueue.operations[ 0]] 一時停止];
ただし、別のサイトから 2 番目のファイルをダウンロードしようとすると (ナビゲートする Web ビューがあります)、それを httpClient.operationQueue に追加すると、同じキューに追加されないようです。つまり、タイマーでこれを呼び出すと、次のようになります。
NSLog(@"Operations %d", httpClient.operationQueue.operations.count);
「オペレーション 2」が表示されませんが、
Operations 1
Operations 1
目的の操作を見つけて何かを実行するために operations.count を取得しようとすると、それが見つからないことがあるため、これは面倒です。それは「並列」キューか何かにあります!
すべてのアクティブな操作を取得して処理する方法はありますか? または、配列を追加するたびに、各操作をある種の配列に保存する方法はありますか? (ただし、読み取り専用の目的ではなく、「それらを使用する」ことができます..一時停止、キャンセルなどの呼び出しなど)
私が何か重要なものを見逃していること、そして私がプログラミングの初心者であることは明らかですが、何か助けていただければ幸いです! (そして、あなたが明示的にできるなら、もっと良い..私は初心者です)
ありがとうございます、本当に。
編集: 少し調査を行い、いくつかのことを試した後、その httpclient をシングルトンに追加し、ランダムな baseurl を使用してアプリの初期化時にのみ設定することで解決しました。次に、その URL に関係なく、各操作をその Singleton-httpClient に追加します。すべての接続が保存され、ループの問題でそれらにアクセスできるようになったので、うまくいくようですが、それは良い方法ではないことはわかっています。より簡単にする必要があり、すべての操作に(異なるURLを使用して)偽のbaseurlを使用して「トリッキーな」httpclientを使用する代わりに、ある種の配列でアクティブな接続を管理する方法が欠けていることを知っています。 ..私はまだアドバイスと良い実践を受け入れています:)。ありがとう!