iOS downloadTaskWithRequest在iPhone上的后台会话上调用时返回nil,在模拟器中工作

时间:2014-03-01 15:08:52

标签: ios objective-c nsurlsession nsurlsessiondownloadtask

- (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];

有什么想法吗?

更新9/12/14: 我再次遇到这个问题,谷歌搜索并找到了这个SO帖子然后看到我是问题的作者!这次约-URLSession:task:didCompleteWithError甚至没有被召唤。解决方案是重新启动我的手机。这必须是Apple的bug。我在iPhone 5s上运行iOS7。

4 个答案:

答案 0 :(得分:1)

您应该实施URLSession:task:didCompleteWithError:,并且应该报告有意义的错误(如果有的话)。

就可能在模拟器而非设备上工作的各种问题而言,它们包括(a)在URL中使用localhost; (b)使用仅在LAN和iOS设备上可用的URL不通过wifi成功连接,例如也许只能通过蜂窝连接;您必须分享有关您要连接的URL类型的更多信息。

根据documentationNSURLErrorDomain错误-999NSURLErrorCancelled。我不清楚为什么你会在这种情况下得到那个特定的错误,除非你明确取消请求或使会话无效。

答案 1 :(得分:0)

就我而言,我能找到解决此问题的方法:

1)调用sharedBackgroundSession函数

2)在该会话上调用downloadTaskWithRequest来测试会话是否正常工作,即返回非零的内容

3)如果#2失败,请在延迟后再试一次:

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

就我而言,第一次尝试有时会失败,有时会成功。但第二次尝试似乎可靠地成功。

答案 2 :(得分:0)

我通过调用[backgroundSession invalidateAndCancel]来修复此问题。我只需要调用一次,之后我删除了代码。

我现在想知道是否应该检测何时无法创建任务,并在尝试任务之前调用invalidateAndCancel

答案 3 :(得分:0)

  1. 需要为NSURLSession调用invalidateAndCancel
  2. 设为nUR您的NSURLSession
  3. 再次创建NSURLSession
  4. 再次创建NSURLSessionDownloadTask
  5. 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];
    }