AFネットワーキング:キュー内のファイルをダウンロードする
-
11-12-2019 - |
質問
私は AFNetworking を使い始めたばかりですが、これまでのところ、Web からデータを取得するだけであれば問題なく動作しています。
しかし、デバイスにダウンロードする必要があるファイルのリストができました。
for(NSDictionary *issueDic in data)
{
Issue *issue = [[Issue alloc] init];
...
[self getOrDownloadCover:issue];
...
}
getOrDownloadCover:issue は、ファイルがローカルに既に存在するかどうかを確認し、存在する場合はそのパスを保存するだけで、存在しない場合は、指定された URL からファイルをダウンロードします。
- (void)getOrDownloadCover:(Issue *)issue
{
NSLog(@"issue.thumb: %@", issue.thumb);
NSString *coverName = [issue.thumb lastPathComponent];
NSLog(@"coverName: %@", coverName);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
__block NSString *filePath = [documentsDirectory stringByAppendingPathComponent:coverName];
if([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
// Cover already exists
issue.thumb_location = filePath;
NSLog(@"issue.thumb_location: %@", filePath);
}
else
{
NSLog(@"load thumb");
// Download the cover
NSURL *url = [NSURL URLWithString:issue.thumb];
AFHTTPClient *httpClient = [[[AFHTTPClient alloc] initWithBaseURL:url] autorelease];
NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET" path:issue.thumb parameters:nil];
AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:filePath append:NO];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
issue.thumb_location = filePath;
NSLog(@"issue.thumb_location: %@", filePath);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"FAILED");
}];
[operation start];
}
}
getOrDownloadCover:issue は連続 20 回呼び出すことができるため、すべてのリクエストをキューに入れる必要があります。キューが完了しても、パスを保存できるはずです (または通知を送信するだけです)。道が何であるかはすでに知っています)
これについて何か提案はありますか?
解決
を追加 NSOperationQueue
たとえば、appDelegate など、アプリケーション内の任意の時点でインスタンスを取得できるオブジェクトに追加します。次に、を追加するだけです AFHTTPRequestOperation
このキューに次のように追加します。
[[(AppDelegate *) [UIApplication sharedApplication].delegate operartionQueue] addOperation:operation];
完了ブロックで保存を処理するだけです。メインスレッドでこのブロックからメソッドを呼び出すか、 NSNotification
.
メインスレッドを呼び出すには、 GCD を使用します。
dispatch_async(dispatch_get_main_queue(), ^{
// Call any method from on the instance that created the operation here.
[self updateGUI]; // example
});
他のヒント
これが役に立つかどうか...
あなた自身のCoperationQueueを使用する代わりに、AfhttpClientのCoperationQueueを使用できます。ENQUEUEHTTPOPERATIONまたはENQUEUEの単一操作またはENQUEUEBATCHOPERATIONSを使用して、(これらのメソッド名をメモリから呼び出す可能性があります)。
各操作に固有のデータを格納する限り、afttpRequestOperationをサブクラス化し、保存したいパスのプロパティを設定できます。このようなもの。