奇怪的NSURLSessionDownloadTask行为通过蜂窝(不是wifi)

Cer*_*ers 13 background cellular-network ios nsurlsession nsurlsessiondownloadtask

我已启用具有远程通知任务的后台模式,以便在应用程序收到推送通知时在后台下载小文件(100kb).我已经使用配置了下载会话

NSURLSessionConfiguration *backgroundConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:sessionIdentifier];
[backgroundConfiguration setAllowsCellularAccess:YES];


self.backgroundSession = [NSURLSession sessionWithConfiguration:backgroundConfiguration
                                                       delegate:self
                                                  delegateQueue:[NSOperationQueue mainQueue]];
Run Code Online (Sandbox Code Playgroud)

并使用激活它

 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[hostComponents URL]];

[request setAllowsCellularAccess:YES];


NSMutableData *bodyMutableData = [NSMutableData data];
[bodyMutableData appendData:[params dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:[bodyMutableData copy]];


_downloadTask =  [self.backgroundSession downloadTaskWithRequest:request];

[self.downloadTask resume];
Run Code Online (Sandbox Code Playgroud)

现在一切正常,只有当我通过Wifi或通过Cellular连接但iPhone连接到xCode的电缆时,如果我断开iPhone并通过蜂窝接收推送通知代码停 [self.downloadTask resume];在线而不调用URL.

处理这些操作的类是NSURLSessionDataDelegate,NSURLSessionDownloadDelegate,NSURLSessionTaskDelegate,因此实现:

    - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
Run Code Online (Sandbox Code Playgroud)

我试图插入一个带有UILocalNotification(现在'现在')的调试行,[self.downloadTask resume]但在5分钟后被调用并说它self.downloadTask.state被'暂停'

是什么导致这种奇怪的行为?

San*_*awy 9

NSURLSessionConfiguration类参考的文档在这里:

https://developer.apple.com/Library/ios/documentation/Foundation/Reference/NSURLSessionConfiguration_class/Reference/Reference.html#//apple_ref/occ/instp/NSURLSessionConfiguration/discretionary

说:对于自由选择的财产:

讨论

设置此标志后,插入电源和Wi-Fi时更有可能发生传输.默认情况下,此值为false.

仅当最初通过调用backgroundSessionConfiguration:方法构造会话的配置对象时才使用此属性,并且仅在应用程序位于前台时启动的任务中使用此属性. 如果在应用程序处于后台时启动任务,则无论此属性的实际值如何,该任务都将被视为自由裁量.对于基于其他配置创建的会话,将忽略此属性.

这似乎意味着如果在后台启动下载,操作系统始终可以自行决定是否以及何时继续下载.在完成这些任务之前,操作系统似乎总是在等待wifi连接.

我的经验支持这个猜想.我发现当设备处于蜂窝状态时,我可以发送几个下载通知.他们仍然卡住了.当我将设备切换到wifi时,它们都会通过.


San*_*awy 0

你在做什么

  • (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{}

您是否在下载完成之前立即调用completionHandler?我相信这样做不会影响Wifi模式下或连接到Xcode时的操作。但不知何故,当在蜂窝网络的后台时,它会使下载停止,直到您连接到 Wifi。