我想知道你是否已经看过这个或者可能有一些想法,为什么我在我的代码中看到以下行为:我有一个背景配置的NSURLsession。当程序在Foreground中运行时,我会启动定期下载任务,一切正常。当我模拟backgroundfetch(在xcode中)时,我的任务获得一个空值(尽管请求和会话不为空)。当然,在这种情况下,我的会话委托永远不会被解雇来完成performhandler。如果我模拟后续的背景提取,它们都会在之后工作。此时,如果我将应用程序带到模拟器中的前台,并且我模拟了另一个backgroundfetch,症状就会出现。我在我的appdelegate类中使用此代码。
非常感谢您的帮助。
- (NSURLSession *)FlickrSession
{
if(!_FlickrSession)
{
NSLog(@"setting new FlickrSession");
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:FLICKR_SESSION];
configuration.allowsCellularAccess = NO;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_FlickrSession = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
_FlickrSession.sessionDescription = FLICKR_SESSION;
NSLog(@" new self is %@", _FlickrSession);
NSLog(@"queue in session %@", dispatch_get_current_queue());
});
}
return _FlickrSession;
}
-(void) startFlickrFetch
{
// initialize session config and the background session
[self.FlickrSession getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks)
{
if(![downloadTasks count])
{
NSLog(@"new downloadtask session %@", self.FlickrSession.sessionDescription);
NSURLRequest *request = [NSURLRequest requestWithURL:[FlickrFetcher URLforRecentGeoreferencedPhotos]];
// NSURLSessionDownloadTask *task = [self.FlickrSession downloadTaskWithURL:[FlickrFetcher URLforRecentGeoreferencedPhotos]];
NSURLSessionDownloadTask *task = [self.FlickrSession downloadTaskWithRequest:request];
task.taskDescription = FLICKR_DOWNLOAD_TASK;
NSLog(@"new request %@", request);
NSLog(@"new downloadtask %@", task);
[task resume];
//task?[task resume]:[self fireBackgroungFetchCompletionHandler];;
//[self fireBackgroungFetchCompletionHandler];
NSLog(@"queue in task %@", dispatch_get_current_queue());
}
else
{
NSLog(@"resuming old downloadtask %d", [downloadTasks count]);
for(NSURLSessionDownloadTask *task in dataTasks) [task resume];
}
}];
NSLog(@"queue outside the block %@", dispatch_get_current_queue());
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// open the file, if there is no managedContext. this is the case wjere the application was launched directly by user
// it did not come from the bckground state;
//need to enable background fetch
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
//[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(documentChangedState) name:UIDocumentStateChangedNotification object: self.document];
NSLog(@"in application didfinishlaunching");
[self openDatabaseFile];
[self startFlickrFetch];
return YES;
}
-(void) application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
self.backgroundFetchCompletionHandler = completionHandler;
if(self.document.documentState == UIDocumentStateNormal)
{
//[self openDatabaseFile];
NSLog(@"in performFetchWithCompletionHandler");
[self startFlickrFetch];
}
}
- (void) application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler
{
self.completionhandler = completionHandler;
NSLog(@"handle event for backgroundURLsession***********");
}
答案 0 :(得分:0)
这可能与后台提取和后台会话的奇怪交互有关,在这种情况下我没有建议。
然而,在后台,iOS不知道等待异步调用,例如getTasksWithCompletionHandler
。您可以通过使用UIBackgroundTaskIdentifier
基于[UIApplication]
开始/结束任务(在这种情况下,在“get(会话)任务完成中使用”end(app)任务“)来包装这些调用来解决此问题处理程序“块”。
但如果您需要的只是一个计数,这就是我所做的,我认为这更简单:
创建一个ivar:
NSMutableSet *activeTaskIDs;
创建任务时,将其添加到集合中:
[activeTaskIDs addObject:@(task.taskIdentifier)];
任务完成后,将其删除。
你可以从那里得到你的计数,没有异步。
†令人困惑的是,不同的类型的任务。我将术语“app tasks”与“session tasks”区分开来。