3

我有一个应用程序,当它通过-[AppDelegate application:didReceiveRemoteNotification:fetchCompletionHandler:]. 推送有效负载包含一个我需要预取的 url,以便在下一次应用程序启动时准备好数据。

该应用程序需要completionHandler在下载完成时调用:

下载操作完成时要执行的块。调用此块时,传入最能描述下载操作结果的获取结果值。您必须调用此处理程序并且应该尽快这样做。有关可能值的列表,请参阅 UIBackgroundFetchResult 类型。

问题是我是否可以做一个简单的请求,或者我是否应该使用此处描述NSURLSession的后台提取之一进行提取

选项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];
}
4

1 回答 1

3

因此,要回答我自己的问题,经过一些测试,选项 2似乎效果很好。我可以使用UIBackgroundTaskIdentifier. 如果我不使用它,下载失败

于 2017-03-31T12:44:51.107 回答