我想知道在后台获取时是否可以进行多次下载(iOS7 Background Fetch)。目前我有一个从大约 6 个 RESTful api 下载数据的应用程序。这些 API 调用使用 NSURLSession 并并行下载数据。这在应用程序处于前台时有效。我已经用我的应用程序实现了后台获取功能,应用程序可以在后台进行更新。不幸的是,当后台提取发生时,只有第一个 API 调用了六次。如果有人可以帮助我,我真的很感激。
这是下载任务的代码。
- (void)start {
self.responseData = [NSMutableData data];
self.isLoginRequest = YES;
self.dateFormatter = [[NSDateFormatter alloc] init];
[self.dateFormatter setDateStyle:NSDateFormatterMediumStyle];
self.apiList = [NSMutableArray array];
NSArray *apis = [self fetchAPIData];
for (API *api in apis) {
NSString *fullURL = [NSString stringWithFormat:@"%@/%@",BASE_URL, api.url];
switch ([api.type integerValue]) {
case 1:
[self.apiList addObject:[[BSJSONInfo alloc] initWithFileType:BSRequestLeadstatus andDownloadSource:fullURL]];
break;
case 2:
[self.apiList addObject:[[BSJSONInfo alloc] initWithFileType:BSRequestParam andDownloadSource:fullURL]];
break;
case 3:
[self.apiList addObject:[[BSJSONInfo alloc] initWithFileType:BSRequestLeadprofiles andDownloadSource:fullURL]];
break;
case 4:
[self.apiList addObject:[[BSJSONInfo alloc] initWithFileType:BSRequestInstallations andDownloadSource:fullURL]];
break;
case 5:
[self.apiList addObject:[[BSJSONInfo alloc] initWithFileType:BSRequestLeadproviders andDownloadSource:fullURL]];
break;
case 6:
[self.apiList addObject:[[BSJSONInfo alloc] initWithFileType:BSRequestSaleorders andDownloadSource:fullURL]];
break;
default:
break;
}
}
[self startAllDownloads:nil];
}
- (void)startAllDownloads:(id)sender {
self.session = [self backgroundSession];
// Access all download info objects using a loop.
for (int i=0; i<[self.apiList count]; i++) {
BSJSONInfo *jsonInfo = [self.apiList objectAtIndex:i];
// Check if a file is already being downloaded or not.
if (!jsonInfo.isDownloading) {
if (jsonInfo.taskIdentifier == -1) {
jsonInfo.downloadTask = [self.session downloadTaskWithURL:[NSURL URLWithString:jsonInfo.downloadSource]];
}
else{
jsonInfo.downloadTask = [self.session downloadTaskWithResumeData:jsonInfo.taskResumeData];
}
jsonInfo.taskIdentifier = jsonInfo.downloadTask.taskIdentifier;
[jsonInfo.downloadTask resume];
jsonInfo.isDownloading = YES;
}
}
}
-(int)getFileDownloadInfoIndexWithTaskIdentifier:(unsigned long)taskIdentifier{
int index = 0;
for (int i=0; i<[self.apiList count]; i++) {
BSJSONInfo *jsonInfo = [self.apiList objectAtIndex:i];
if (jsonInfo.taskIdentifier == taskIdentifier) {
index = i;
break;
}
}
return index;
}
- (NSURLSession *)backgroundSession
{
static NSURLSession *session = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:[NSString stringWithFormat:@"%@", SESSION_STRING]];
configuration.timeoutIntervalForRequest = 30.0;
configuration.timeoutIntervalForResource = 60.0;
session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
});
return session;
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)downloadURL
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *URLs = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *documentsDirectory = [URLs objectAtIndex:0];
NSURL *originalURL = [[downloadTask originalRequest] URL];
NSURL *destinationURL = [documentsDirectory URLByAppendingPathComponent:[originalURL lastPathComponent]];
NSError *errorCopy;
[fileManager removeItemAtURL:destinationURL error:NULL];
BOOL success = [fileManager copyItemAtURL:downloadURL toURL:destinationURL error:&errorCopy];
if (success){
int index = [self getFileDownloadInfoIndexWithTaskIdentifier:downloadTask.taskIdentifier];
BSJSONInfo *jsonInfo = [self.apiList objectAtIndex:index];
jsonInfo.isDownloading = NO;
jsonInfo.downloadComplete = YES;
jsonInfo.taskIdentifier = -1;
jsonInfo.taskResumeData = nil;
//Let parser to parse the JSON
dispatch_async(dispatch_get_main_queue(), ^{
self.responseData = [NSData dataWithContentsOfURL:destinationURL];
[self parsingJSONResponse:self.responseData withType:jsonInfo.type];
});
}
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
if (error != nil) {
self.networkError = error;
[self.delegate downloadingError:[error localizedDescription]];
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate downloadingError:[NSString stringWithFormat:@"%@ for type %lu", [error localizedDescription], self.bsType]];
return;
});
}
self.downloadTask = nil;
}
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {
BSAppDelegate *appDelegate = (BSAppDelegate *)[[UIApplication sharedApplication] delegate];
// Check if all download tasks have been finished.
[self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
if ([downloadTasks count] == 0) {
if (appDelegate.backgroundSessionCompletionHandler != nil) {
void(^completionHandler)() = appDelegate.backgroundSessionCompletionHandler;
appDelegate.backgroundSessionCompletionHandler = nil;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
completionHandler();
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.alertBody = @"All files have been downloaded!";
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}];
}
}
}];
}
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{
// BLog();
}
谢谢