AppsDev
AppsDev

Reputation: 12509

Most appropiate way to continue an NSURLConnection request in background

I'm developing an app which performs several HTTP requests to RESTful services by using asynchronous NSURLConnection connections and implementing the NSURLConnectionDelegate protocol to proccess their responses. Users may put the app in background or an interruption may occur before the response is received and delegate's connectionDidFinishLoading: method is called (thus, when I say here background I mean the app to go to background/suspended state, I don't mean tasks being performed in background threads while the app in foreground), so I'd need those network requests to continue in background to be completed.

I've read the "Background Execution" section of the App Programming Guide for iOS documentation, but I'm not sure which of the given options should I follow for my scenario:

1) To see my network requests as "finite-length tasks" and request some extra time to complete them when performing the service's calls

2) To see them as "downloading content in the background" (I call RESTful services to get some JSON data as response). In such case, it seems that I need to use NSURLSession objects...

Thanks in advance

Upvotes: 0

Views: 663

Answers (2)

DannyC
DannyC

Reputation: 411

NSUrlSession is what you need if you are targeting iOS 7 and above. The 10 minute background task mentioned in the other answer only applies to iOS 6 and below.

NSUrlSession: https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/index.html#//apple_ref/occ/instm/NSURLSession

Apple's Simple Background Transfer sample project: https://developer.apple.com/library/ios/samplecode/SimpleBackgroundTransfer/Introduction/Intro.html#//apple_ref/doc/uid/DTS40013416

Upvotes: 0

kabarga
kabarga

Reputation: 803

1) You can background your app threads and you will have up to 10 mins to finish your requests. Add method below to the AppDelegate:

@property (nonatomic, assign) UIBackgroundTaskIdentifier bgTask;

- (void) startBackgroundingTask
{
    if ( _bgTask != UIBackgroundTaskInvalid ) {
        [[UIApplication sharedApplication] endBackgroundTask:_bgTask];
        _bgTask = UIBackgroundTaskInvalid;
    }

    self.bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        dispatch_async( dispatch_get_main_queue(), ^{
            if (self.bgTask != UIBackgroundTaskInvalid ) {
                [[UIApplication sharedApplication] endBackgroundTask:self.bgTask];
                self.bgTask = UIBackgroundTaskInvalid;
                [self performSelector:@selector(startBackgroundingTask) withObject:nil afterDelay:1.0];
            }
        });
    }];
}

And call it once in:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

Upvotes: 1

Related Questions