我已经实现了代码,以便在20个批次中下载大小为1-2 MB的块。一旦会话完成了前20个下载请求,它将在会话中设置新的20个请求。我已经在控制台日志中的真实设备上测试了它并找到了它。
default 15:56:03.627080 +0800 xyz __nw_socket_service_writes_block_invoke sendmsg(fd 14, 31 bytes): socket has been closed
default 15:56:03.671468 +0800 mediaserverd -CMSessionMgr- cmsmHandleApplicationStateChange: CMSession: Client com.xyz with pid '1447' is now Background Suspended. Background entitlement: NO
default 15:56:03.671804 +0800 mediaserverd 1067: pid 1447(xyz)
default 15:56:03.672156 +0800 mediaserverd 3138: sid:0x1a653, xyz(1447), 'prim' new state = Background Task Suspended
default 15:56:03.673578 +0800 locationd Client com.xyz disconnected
default 15:56:03.694200 +0800 symptomsd 1447 com.xyz: BackgroundTaskSuspended (most elevated: BackgroundTaskSuspended)
default 15:56:03.716198 +0800 symptomsd Entry, display name com.xyz uuid 02184FD5-F48B-3EF7-B2B6-98AB05145DB9 pid 1447 isFront 0
有时会遇到这个问题。
Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory" UserInfo={NSErrorFailingURLKey`enter code here`
Code = 2与设备资源有关。
我的问题是我们可以在下载批量后下载并请求更多文件。或者后台模式仅适用于正在进行的请求并暂停应用程序,但会继续批量下载已发送任务中提到的文件。
这是BG任务的代码,
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) {
backgroundConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:[[NSBundle mainBundle] bundleIdentifier]];
} else {
backgroundConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"downloadmanager"];
}
backgroundConfiguration.discretionary = YES;
backgroundConfiguration.sessionSendsLaunchEvents = YES;
self.backgroundSession = [NSURLSession sessionWithConfiguration:backgroundConfiguration delegate:self delegateQueue:NSOperationQueue.mainQueue];
在BG任务中添加NSURLRequest的代码,
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDownloadTask *downloadTask;
downloadTask = [self.backgroundSession downloadTaskWithRequest:request];
AppDelegate中的后台任务处理程序
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
DownloadManager.shared().backgroundTransferCompletionHandler = completionHandler
print("background task called")
}
在BG中发送应用后,代理会在控制台中停止打印日志。我可以看到它已经部分下载了文件。
- (void)URLSession:(NSURLSession *)session
downloadTask:(NSURLSessionDownloadTask *)downloadTask
didWriteData:(int64_t)bytesWritten
totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
NSLog(@"Byte downlaoded %lld of %lld ", bytesWritten, totalBytesWritten);
}
答案 0 :(得分:1)
在后台队列中下载多个请求真是太难了。所以我建议你使用Dispatch Groups。请按照以下步骤操作:
步骤1:您可以在一个Dispatch Groups中对20个请求进行分组,为了使您的请求达到平衡,您可以为每个连接设置最大并发请求队列。我认为2个连接是最好的连接
第2步:使用Dispatch Groups时。它可以在完成所有20个请求后通知,然后您可以为新的20个请求创建另外的Dispatch Groups。
请参阅调度组https://www.allaboutswift.com/dev/2016/7/12/gcd-with-swfit3
答案 1 :(得分:1)
我已经实现了后台会话,以便在后台但以串行方式下载多个文件。
但是要实现此功能存在很多挑战。如果操作系统将更多资源用于其他应用程序,它将优先于该应用程序而不是您的应用程序,因此当您启动后台会话时,您应该将远程超时设置为20分钟以下载文件。 20分钟后,它将导致错误的远程超时,并且将无法在后台下载2 mb的文件,而在前台运行应用程序时,它将无法正常运行。
相反,当应用程序在后台运行时,您会发现在前台模式下仅几秒钟就下载了2 mb的文件,这会在20分钟后引发错误(远程超时)。
这很奇怪。。。我发现有一种解决方案,当您尝试在后台模式下下载文件时,请确保已将设备连接到充电电缆,并且发现下载会很有趣。
尝试一下!!!!!!
如有任何疑问,请告诉我。
答案 2 :(得分:0)
我认为你是在一个队列中下载文件,破坏了会话并尝试在另一个队列中读取它。