Domanda

- (NSURLSession *)sharedBackgroundSession
{
    static NSURLSession *sharedBackgroundSession = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.example.apple-samplecode.SimpleBackgroundTransfer.BackgroundSession"];
        configuration.URLCache = [NSURLCache sharedURLCache];
        configuration.requestCachePolicy = NSURLRequestReturnCacheDataElseLoad;
        sharedBackgroundSession = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
    });
    return sharedBackgroundSession;
}

// When executed on simulator, things work as expected, I never get a nil result.
// When executed on iPhone 5s device, nextDownloadTask is always nil
NSURLSessionDownloadTask *nextDownloadTask = [[self sharedBackgroundSession] downloadTaskWithRequest:request];

Any ideas?

UPDATE 9/12/14: I had this issue again, googled and found this SO post and then saw that I was the author of the question! This time around -URLSession:task:didCompleteWithError wasn't even getting called. THE SOLUTION WAS TO RESTART MY PHONE. This must be an Apple bug. I'm running iOS7 on my iPhone 5s.

È stato utile?

Soluzione

You should implement URLSession:task:didCompleteWithError: and it should report meaningful errors, if any.

In terms of sorts of issues that would work on simulator and not the device, they include (a) use of localhost in the URL; (b) use of URLs only available on LAN and iOS device not connecting successfully via wifi, e.g. perhaps only connecting via cellular; etc. You'd have to share more about the type of URL you are connecting to.

According to the documentation, NSURLErrorDomain error -999 is NSURLErrorCancelled. I'm unclear as to why you would get that particular error in this context, unless you were explicitly canceling the request or invalidating the session.

Altri suggerimenti

In my case, I was able to find a workaround for this problem:

1) Call the sharedBackgroundSession function

2) Call downloadTaskWithRequest on that session to test if the session is working properly, i.e. returning something non-nil

3) If #2 fails, then try again after a delay:

[_sharedBackgroundSession performSelector:@selector(sharedBackgroundSession) withObject:nil afterDelay:0.01];

In my case, the first attempt sometimes fails, sometimes succeeds. But the second attempt seems to reliably succeed.

I fixed this by calling [backgroundSession invalidateAndCancel]. I only had to call this once and after that I removed the code.

I'm now wondering if I should detect when tasks can no longer be created and call invalidateAndCancel before trying anymore tasks.

  1. Need to call invalidateAndCancel for your NSURLSession
  2. Set to nil your NSURLSession
  3. Create again NSURLSession
  4. Create again NSURLSessionDownloadTask

e.g.

NSURLSessionDownloadTask *dataTask = [self.yourSession downloadTaskWithRequest:urlRequest];
NSInteger attemptsNumber = 5;
for (NSUInteger attempts = 0; !dataTask && attempts < attemptsNumber; attempts++){
    [self.yourSession invalidateAndCancel];
    self.yourSession = nil;

    NSURLSessionConfiguration *backgroundConfig = [NSURLSessionConfiguration backgroundSessionConfiguration:[[NSBundle mainBundle] bundleIdentifier]];
    self.yourSession = [NSURLSession sessionWithConfiguration:backgroundConfig delegate:self delegateQueue:nil];
    dataTask = [self.yourSession downloadTaskWithRequest:urlRequest];
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top