我有一个应用程序,当它通过-[AppDelegate application:didReceiveRemoteNotification:fetchCompletionHandler:]
处于非活动状态时接收静音推送。推送有效负载包含一个我需要预取的URL,以便在下次应用启动时准备好数据。
应用需要在下载完成时调用completionHandler
:
下载操作完成时要执行的块。调用此块时,传入最能描述下载操作结果的获取结果值。您必须调用此处理程序,并应尽快执行此操作。有关可能值的列表,请参阅UIBackgroundFetchResult类型。
问题是我是否可以执行简单的NSURLSession
请求,或者我是否应该使用后台提取as described here进行提取
选项1:使用简单的NSURLSession
并调用回调
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
{
NSURL *url = [NSURL URLWithString:userInfo[@"my-data-url"]];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:url] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// save the result & call the
completionHandler(data ? UIBackgroundFetchResultNewData : UIBackgroundFetchResultNoData);
}];
[task resume];
}
选项2:使用额外的后台处理来下载内容
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
{
NSURLSessionDataTask *task;
__block UIBackgroundTaskIdentifier backgroundId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
// time's up, cancel the download
[application endBackgroundTask:backgroundId];
backgroundId = UIBackgroundTaskInvalid;
completionHandler(UIBackgroundFetchResultFailed);
[task cancel];
}];
NSURL *url = [NSURL URLWithString:userInfo[@"my-data-url"]];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:url] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// check if time was up
if(backgroundId == UIBackgroundTaskInvalid) {
return;
}
[application endBackgroundTask:backgroundId];
backgroundId = UIBackgroundTaskInvalid;
// save the result & call the
completionHandler(data ? UIBackgroundFetchResultNewData : UIBackgroundFetchResultNoData);
}];
[task resume];
}
答案 0 :(得分:2)
因此,为了回答我自己的问题,经过一些测试后,选项2 的效果非常好。我可以使用UIBackgroundTaskIdentifier
下载我需要的任何数据。如果我不使用它,则下载失败