AF네트워킹:대기열에 있는 파일 다운로드 중
-
11-12-2019 - |
문제
방금 AFNetworking을 사용하기 시작했고 지금까지는 웹에서 데이터를 가져오는 데만 잘 작동했습니다.
하지만 이제 기기에 다운로드해야 하는 파일 목록이 생겼습니다.
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
});
다른 팁
이것이 도움이되는지 확실하지 않지만 ...
자신의 OrchantQueue를 사용하는 대신 AfhttpClient의 Orchangeue를 사용할 수 있습니다.enqueuehttpoperation 또는 kenqueue로 단일 작업 entqueueBatchOperations로 작업 배열 (메모리에서 이러한 메소드 이름을 호출 할 가능성이 높습니다).
각 조작에 특정한 데이터를 저장하는 한, AFHTTPRequestOperation을 하위 클래스하고 저장할 경로의 속성을 설정할 수 있습니다.이 같은.