首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用NSURLSessionConfiguration实现iOS后台下载

使用NSURLSessionConfiguration实现iOS后台下载
EN

Stack Overflow用户
提问于 2018-05-18 16:10:26
回答 3查看 876关注 0票数 0

我已经实现了批量下载大小为1-2MB的块的代码,每批20个。一旦会话完成了前20个下载请求,它将在会话中设置新的批量20个请求。我已经在控制台日志中的真实设备上进行了测试,并发现了这一点。

代码语言:javascript
复制
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

有时会遇到这个问题。

代码语言:javascript
复制
Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory" UserInfo={NSErrorFailingURLKey`enter code here`

Code=2是与设备资源相关的东西。

我的问题是,在下载一批文件后,我们是否可以在后台下载和请求更多的文件。或者后台模式仅对正在进行的请求起作用,挂起应用,但继续批量下载已发送任务中提到的文件。

这是BG任务的代码,

代码语言:javascript
复制
  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的代码

代码语言:javascript
复制
 NSURLRequest *request = [NSURLRequest requestWithURL:url];
        NSURLSessionDownloadTask *downloadTask;
            downloadTask = [self.backgroundSession downloadTaskWithRequest:request];

AppDelegate中的后台任务处理程序

代码语言:javascript
复制
  func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {

        DownloadManager.shared().backgroundTransferCompletionHandler = completionHandler
        print("background task called")
    }

在BG进度中发送app后,代理将在控制台中停止打印日志一段时间。我可以看到它已经下载了部分文件。

代码语言:javascript
复制
- (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);

}
EN

回答 3

Stack Overflow用户

发布于 2018-05-23 12:20:28

在后台队列中下载多个请求太难了。因此,我建议您使用调度组。请执行以下步骤:

Step1:您可以将20个请求分组到一个调度组中,为了使您的请求达到平衡,您可以设置每个连接的最大并发请求队列。我认为每个连接2个并发是最好的。

Step2:当您使用调度组时。它可以在所有20个请求完成后通知,然后您可以为新的20个请求创建另一个调度组。

阅读此内容以了解调度组https://www.allaboutswift.com/dev/2016/7/12/gcd-with-swfit3

票数 1
EN

Stack Overflow用户

发布于 2018-07-02 18:11:53

我已经实现了后台会话,在后台以串行方式下载多个文件。

但要实现这一功能还有很多挑战。如果操作系统为其他应用程序使用了更多资源,它会将优先级给予该应用程序,而不是您的应用程序。因此,当您启动后台会话时,您应该将远程超时设置为20分钟以下载文件。它将抛出一个错误,远程超时20分钟后,它将无法下载2mb的文件在后台,它将顺利地工作时,你在前台运行的应用程序。

你可以发现在前台模式下下载的2MB文件只需要几秒钟,而当应用程序在后台时,它将在20分钟后抛出一个错误(远程超时)。

这很奇怪..。我发现有一种解决方案,当你试图在后台模式下下载文件时,确保你的设备连接到充电线上,你会发现下载会像魔咒一样工作。

试试这个!

如果您有任何疑问,请让我知道。

票数 1
EN

Stack Overflow用户

发布于 2018-05-18 16:23:00

我认为您正在下载一个队列中的文件,销毁了会话,然后尝试在另一个队列中读取它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50406691

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档