I want to try a post call on my server till it success, I would like to try it each 30 seconds.
So I am using NSURLSession for my call:
NSURLSessionDownloadTask *task = [self.session downloadTaskWithRequest:request];
task.taskDescription = [NSString stringWithFormat:@"Downloading file %@", [path lastPathComponent]];
[task resume];
Then if an error occur (no network for example) I have an error in:
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
My question is how to do the same call in 30 seconds will my app is in background?
I tried with dispatch, NSThread and performSelector but looks like it does not work in background :(
Thanks.
A few observations:
If you want to try again in 30 seconds, even if the app is no longer in the foreground, you will presumably just want to ask the OS for a little extra time to perform a finite length task. See Executing Finite-Length Tasks. If you do that, your standard timer, dispatch_after
, or whatever, should work fine.
Note you only have 3 minutes to complete this background task. I know you said that you would be inclined to just try again in 30 seconds, but I personally suspect that if a user doesn't have connectivity, there's a good chance that they might not have connectivity within the next few minutes, either.
By the way, if retrying while the app is still running, I might advise against trying again in 30 seconds. Better, in my opinion, is to use Reachability so that you are notified when the network becomes available. There's no point in trying again until the network is re-established.
Another approach is to use backgroundSessionConfigurationWithIdentifier
of NSURLSessionConfiguration
. See Downloading Content in the Background. If you do this, you have more than 3 minutes for the request to finish. And it will automatically start as soon as connectivity is re-established. The disadvantages of this technique are that (a) the background sessions aren't quite as responsive as foreground sessions; (b) it's limited to iOS 7 and later; and (c) you have to implement delegate-based rendition of NSURLSession
rather than completion block rendition, which is a little more work.
Frankly, I'd generally be inclined to pursue the third approach, but each has its merits.