いくつかの反応:
NSURLConnection
connectionWithRequest
(メソッドをトリガーする) を開始していますNSURLConnectionDataDelegate
が、明らかにそれを無視して を開始していdataWithContentsOfURL
ます。どちらかを選択する必要がありますが、両方を実行しないでください。
NSOperation
絶対に (a) 同時実行を楽しみたいので、ベースのソリューションを追求することをお勧めします。ただし、(b) 同時操作を妥当な数 (たとえば 4 または 5) に制限します。そうしないと、リクエストがタイムアウトして失敗します。
ファイル名の取得に関してはlastPathComponent
、NSURL
. (以下で使用する私のダウンロード操作は、明示的なファイル名を指定しない場合、実際には自動的にこれを使用します。)
リモート サーバーからファイル名のリストを取得する方法を説明していないので、どの画像を取得する必要があるかを知る方法を確認する必要があります。
これがあなた自身の目的であれば問題ありませんが、セルラー接続で大量のデータを要求するアプリを Apple が拒否するという主張を聞いたことがあります (そして 2000 枚の画像は確かに資格があります)。率直に言って、Apple が大騒ぎしなくても、データ プランをそれほど多く使用する前に、ユーザーに尋ねる必要があります。Reachabilityを使用して、ユーザーが Wi-Fi 経由で接続しているかセルラー経由で接続しているかを判断できます。後者の場合は、警告を表示することができます。
しかし、私は次のようなものを提案したいと思います (URL のバージョンをいくつか持っていると仮定しますNSArray
... NSString
URL のリストがどのような形式であっても、明らかにこれを調整します):
NSOperationQueue *downloadQueue = [[NSOperationQueue alloc] init];
downloadQueue.maxConcurrentOperationCount = 4;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
for (NSString *urlString in urlStrings)
{
NSURL *url = [NSURL URLWithString:urlString];
NSString *path = [docsPath stringByAppendingPathComponent:[url lastPathComponent]];
if (![fileManager fileExistsAtPath:path]) {
DownloadOperation *downloadOperation = [[DownloadOperation alloc] initWithURL:url];
downloadOperation.downloadCompletionBlock = ^(DownloadOperation *operation, BOOL success, NSError *error) {
if (error) NSLog(@"download of %@ failed: %@", operation.url, error);
};
[downloadQueue addOperation:downloadOperation];
}
}
そして、そのダウンロード操作は次のようなものかもしれません。明らかに、必要なNSOperation
ベースのダウンローダーを使用しますが、ダウンロード全体をメモリにロードするのではなく、永続ストレージに直接ストリーミングするダウンローダーを使用することをお勧めします。
それほど派手にしたくない場合は、次のようにすることができます。
NSOperationQueue *downloadQueue = [[NSOperationQueue alloc] init];
downloadQueue.maxConcurrentOperationCount = 4;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
for (NSString *urlString in urlStrings)
{
NSURL *url = [NSURL URLWithString:urlString];
NSString *path = [docsPath stringByAppendingPathComponent:[url lastPathComponent]];
if (![fileManager fileExistsAtPath:path]) {
[downloadQueue addOperationWithBlock:^{
NSString *path = [docsPath stringByAppendingPathComponent:[url lastPathComponent]];
NSData *data = [NSData dataWithContentsOfURL:url];
if (data)
[data writeToFile:path atomically:YES];
}];
}
}
明らかに、ダウンロードに必要なダウンロード操作クラスを使用しますが、基本的な考え方を理解していただければ幸いです。ベースのダウンロードを作成し、NSOperation
ダウンロードが必要なファイルごとに 1 つ送信します。