从静默远程通知加载数据

Loading data from a silent remote notification

我有一个应用程序,当它处于非活动状态时,它会通过 -[AppDelegate application:didReceiveRemoteNotification:fetchCompletionHandler:] 接收静默推送。推送负载包含一个 url,我需要预取它以便数据在下次应用程序启动时准备就绪。

应用程序需要在下载完成后调用 completionHandler

The block to execute when the download operation is complete. When calling this block, pass in the fetch result value that best describes the results of your download operation. You must call this handler and should do so as soon as possible. For a list of possible values, see the UIBackgroundFetchResult type.

问题是我是否可以做一个简单的 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];
}

因此,为了回答我自己的问题,经过一些测试,选项 2 似乎工作得很好。我可以使用 UIBackgroundTaskIdentifier 下载我需要的任何数据。如果我不使用它,下载失败