iosbackgroundnsurlsessionnsurlsessionconfiguration

Cannot get background URL Session to return


I have tried and failed many times to get some inherited code to successfully send a background session request. When in the foreground, it works flawlessly, but in the background it will either never return, or, in some cases, receive a auth challenge.

The code to create the request is pretty boilerplate:

NSURLSessionConfiguration *sessionConfig =
[NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:identifier];
sessionConfig.sessionSendsLaunchEvents = true;
sessionConfig.discretionary = false;
sessionConfig.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
sessionConfig.timeoutIntervalForResource = 60 * 60 * 24; //One day. Default is 7 days!

/* Create session, and optionally set a NSURLSessionDelegate. */
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig
                                                      delegate:self
                                                 delegateQueue:[NSOperationQueue mainQueue]];

NSURLComponents *urlComponents = [NSURLComponents new];
urlComponents.scheme           = @"https";
urlComponents.host             = @"jsonplaceholder.typicode.com";
urlComponents.path             = @"/posts/1";

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[urlComponents URL]];
request.HTTPMethod           = @"PUT";

NSLog(@"Making request: %@", request);

/* Start a new Task */
NSURLSessionDataTask *task = [session dataTaskWithRequest:request];
[task resume];

But I never get anything back. I do have the required background modes (probably)

      <key>UIBackgroundModes</key>
      <array>
              <string>fetch</string>
              <string>remote-notification</string>
      </array>

and my delegate is delegating everything

<NSURLSessionDelegate, NSURLSessionDataDelegate,NSURLConnectionDataDelegate,NSURLConnectionDelegate,NSURLSessionTaskDelegate>

Any help would be appreciated- I'm pretty sure I'm missing just one line of code somewhere. I even went so far as to create a GitHub repo just to test this code out- it schedules a Local Notification to allow you to run the session task in the background.

GitHub repo for BackgroundSender


Solution

  • In the app delegate's handleEventsForBackgroundURLSession, you are doing nothing with the completion handler. You should:


    By the way, you shouldn't use data tasks with background sessions. You generally should use a download or upload task.


    Also, those background modes are not necessary for background NSURLSession. Background fetch is designed for a different problem, namely periodically polling to see if your server has data available. If you need that, then by all means, use the fetch background mode, but realize that this is a separate topic from merely performing background requests.

    See Fetching Small Amounts of Content Opportunistically in the App Programming Guide for iOS: Background Execution for a discussion of background fetch, and compare that to the Downloading Content in the Background section.

    Likewise, the remote-notification key is unrelated, too. As the docs say, remote-notification is used when "The app wants to start downloading content when a push notification arrives. Use this notification to minimize the delay in showing content related to the push notification."