0

私は 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を使用する代わりに、ある種の配列でアクティブな接続を管理する方法が欠けていることを知っています。 ..私はまだアドバイスと良い実践を受け入れています:)。ありがとう!

4

1 に答える 1

3

事前にいくつかのヒントがあります。NSOperationQueue と NSOperation API doc の両方を読むことを強くお勧めします。

NSOperationQueue: https://developer.apple.com/library/ios/documentation/Cocoa/Reference/NSOperationQueue_class/Reference/Reference.html#//apple_ref/doc/uid/TP40004592

NSOperation: https://developer.apple.com/library/ios/documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html#//apple_ref/doc/uid/TP40004591

NSOperationQueue の操作配列を繰り返し処理することはお勧めしません。なんで?高いため、おそらく競合状態の問題で終了します。

でも。次のアプローチをお勧めします。

1) シングルトン クラスで NSDictionary を作成します。ここで、キー: ファイル名を表します。値: その要求に関連付けられた AFDownloadRequestOperation 要求。

2) 新しいファイルをダウンロードする必要がある場合: 辞書に存在するかどうかを確認し、新しい操作を作成して辞書に追加しない場合。

2.1) 存在する場合: 2.1.1) AFDownloadRequestOperation は NSOperation から拡張されているため、キャンセルできます。この条件を確認する前にこれを行うには: isExecuting、isFinished。これらの条件のいずれかが false の場合は、操作をキャンセルして辞書から削除できます。

于 2013-09-12T01:28:13.693 に答える