如何通过 NSOperationQueue 从多个 url 下载多个文件
How to download multiple files from multiple url by NSOperationQueue
我正在努力使用 AFNetworking 实现多个文件的下载机制。我想从多个 url 中一个接一个地下载带有进度消息的 zip 文件。我试过像下面的代码,但出现错误 -
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSOperationQueue addOperation:]: operation is already enqueued on a queue'
这是我的代码部分:
- (void) downloadCarContents:(NSArray *)urlArray forContent:(NSArray *)contentPaths {
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
for (int i=0; i< urlArray.count; i++) {
NSString *destinationPath = [self.documentDirectory getDownloadContentPath:contentPaths[i]];
NSLog(@"Dest : %@", destinationPath);
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFHTTPRequestOperation *operation = [manager GET:urlArray[i]
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error : %ld", (long)error.code);
}];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:destinationPath append:NO];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
float percentage = (float) (totalBytesRead * 100) / totalBytesExpectedToRead;
[self.delegate downloadProgression:percentage];
}];
[operationQueue addOperation:operation];
}
}
请帮忙。
当您调用 GET
时,它已经添加到 AFHTTPRequestionOperationManager
的 operationQueue
中。所以不要再将它添加到队列中。
此外,您应该在循环之前实例化 AFHTTPRequestOperationManager
一次,而不是在循环中重复。
此代码还有其他问题,但与其尝试解决所有这些问题,我建议您过渡到使用 NSURLSession
的 AFHTTPSessionManager
。旧的 AFHTTPRequestOperationManager
基于 NSURLConnection
,但 NSURLConnection
现在已弃用。而且,事实上,AFNetworking 3.0 已经完全退役 AFHTTPRequestOperationManager
。
因此,AFHTTPSessionManager
再现可能如下所示:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
for (NSInteger i = 0; i < urlArray.count; i++) {
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlArray[i]]];
NSURLSessionTask *task = [manager downloadTaskWithRequest:request progress:^(NSProgress *downloadProgress) {
[self.delegate downloadProgression:downloadProgress.fractionCompleted * 100.0];
} destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
return [NSURL fileURLWithPath:[self.documentDirectory getDownloadContentPath:contentPaths[i]]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
NSLog(@"File downloaded to: %@", filePath);
NSLog(@"Error: %@" error.localizedDescription);
}];
[task resume];
}
我正在努力使用 AFNetworking 实现多个文件的下载机制。我想从多个 url 中一个接一个地下载带有进度消息的 zip 文件。我试过像下面的代码,但出现错误 -
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSOperationQueue addOperation:]: operation is already enqueued on a queue'
这是我的代码部分:
- (void) downloadCarContents:(NSArray *)urlArray forContent:(NSArray *)contentPaths {
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
for (int i=0; i< urlArray.count; i++) {
NSString *destinationPath = [self.documentDirectory getDownloadContentPath:contentPaths[i]];
NSLog(@"Dest : %@", destinationPath);
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFHTTPRequestOperation *operation = [manager GET:urlArray[i]
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error : %ld", (long)error.code);
}];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:destinationPath append:NO];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
float percentage = (float) (totalBytesRead * 100) / totalBytesExpectedToRead;
[self.delegate downloadProgression:percentage];
}];
[operationQueue addOperation:operation];
}
}
请帮忙。
当您调用 GET
时,它已经添加到 AFHTTPRequestionOperationManager
的 operationQueue
中。所以不要再将它添加到队列中。
此外,您应该在循环之前实例化 AFHTTPRequestOperationManager
一次,而不是在循环中重复。
此代码还有其他问题,但与其尝试解决所有这些问题,我建议您过渡到使用 NSURLSession
的 AFHTTPSessionManager
。旧的 AFHTTPRequestOperationManager
基于 NSURLConnection
,但 NSURLConnection
现在已弃用。而且,事实上,AFNetworking 3.0 已经完全退役 AFHTTPRequestOperationManager
。
因此,AFHTTPSessionManager
再现可能如下所示:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
for (NSInteger i = 0; i < urlArray.count; i++) {
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlArray[i]]];
NSURLSessionTask *task = [manager downloadTaskWithRequest:request progress:^(NSProgress *downloadProgress) {
[self.delegate downloadProgression:downloadProgress.fractionCompleted * 100.0];
} destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
return [NSURL fileURLWithPath:[self.documentDirectory getDownloadContentPath:contentPaths[i]]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
NSLog(@"File downloaded to: %@", filePath);
NSLog(@"Error: %@" error.localizedDescription);
}];
[task resume];
}