- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试访问NSURLSession
之前下载的文件。似乎我无法读取文件的位置,即使我在委托方法结束之前正在执行该操作(因为文件是临时的)。
不过,尝试访问nil
和错误257返回的位置下的数据时,我仍收到NSURLSession delegate
。
代码如下:
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
NSError *movingError = nil;
NSData *fileData = [NSData dataWithContentsOfFile:location.path options:0 error:&movingError]; // is nil
NSLog(@"%@", movingError); // is error 257
}
最佳答案
讨论晚了,但是我看到了相同/相似的问题并进行了调查。
通过我的调查,您所看到的是预期的(我应该说“已观察到”吗?)。
但是,由于我不确定100%是否使用URL会话,因此我将要尝试的内容放在下面,然后是我的观察(仅重要的观察)。
另外,我创建了一个sample project并将其放在downLoader.zip中。您可以播放并检查URL会话后台下载的工作方式。但是最好先通读以下内容,然后再尝试演奏,尽管这是一个很长的音符。
答:我要做什么
我正在开发一种地图应用程序,我需要一次下载1000多个小尺寸(0.5-150kB,主要是〜20kB)PNG文件。它们的总下载大小约为50MB,需要花费几分钟的时间来下载所有它们。我认为让用户等待我的应用程序等待下载是错误的设计,因此我使该应用程序使用URL Session的后台下载。
但是,我不得不承认here表示“优化了后台会话,以便传输少量可以在必要时恢复的大型资源。”因此,我使用后台会话的方式是完全相反的。但不管怎么说...
我观察到的
在下面,我列出了我的观察结果以及对原因的猜测。我应该说猜测,因为它们没有记录在案。
(1)观察:有时,didFinishDownlaodingTo随附的文件不存在。
临时文件位于:
/ var / mobile /容器/数据/应用程序/randomHexString/Library/Caches/com.apple.nsurlsessiond/Downloads/yourName.yourApp。应用运行时,randomHexString会发生变化。如果文件不存在,则didFinishDownloadingTo随附的randomHexString是“上一个”会话中的一个。现在,“上一个”是指应用程序上次运行的会话!,当前运行时的当前会话显然不存在该会话。
对于不存在的文件,还有另一种情况,即randomHexString可以,但是文件不存在。这似乎发生在请求取消会话之后(invalidateAndCancel),而在会话变为无效之前(didBecomeInvalidWithError)。
猜猜:这种情况尤其发生在开发阶段,因为我们在下载时手动,通过调试器或仅通过bug终止了应用程序。似乎将下载请求提交给操作系统后,即使应用程序退出,操作系统也会处理我们的请求。请注意,我们无法确定操作系统是否确实接受了请求。即使从URLSessionDownloadTask:resume()返回后,有时文件也不会在下次启动时退出,而有时会退出。
解决方法:如果文件不存在,请忽略它们。一段时间后,应该会出现“这次”的文件。
(2)观察:有时,重复的(相同)文件带有didFinishDownloadingTo。
我的应用程序将下载的PNG文件转换为其他格式。在didFinishDownlaodingTo中,我将临时文件(==操作系统指定)移动到另一个我的应用程序目录中,然后生成线程(GCD)转换格式并删除下载的临时文件。因此,另一个要覆盖的线程(didFinishDownlaodingTo)是一个问题。
解决方法:我列出URLSessionTask:taskIdentifier并在didFinishDownlaodingTo中,通过检索taskID列表来检查重复项,以忽略重复的文件。
(3)观察:即使用户终止了该应用程序,操作系统仍会重新启动该应用程序。
用户从任务切换器终止应用程序后,操作系统通常会通过应用程序:handleEventsForBackgroundURLSession:completionHandler重新启动应用程序。
请注意,重新启动的顺序是didFinishLaunchingWithOptions首先作为常规启动出现,然后是handleEventsForBackgroundURLSession。
从用户的角度来看,当他/她终止应用程序时,就完成了!即使他们终止了该应用程序,它看起来仍然很奇怪,它本身会重新启动并通知他们一些东西。就像僵尸一样。
猜猜:Apple’s doc说“如果用户终止您的应用程序,系统将取消所有待处理的任务”。 “待处理任务”的定义没有明确说明,但我知道这是来自iOS POV,而不是用户或程序开发人员的。正如(1)中所猜测的,iOS似乎已经接受了下载请求,并且它们不再是“待处理的任务”。
解决方法:将所有下载请求都发送到带有URLSessionDownloadTask:resume()的iOS后,创建一个“flagFile”,该文件表示“正在进行下载”。当用户终止应用程序时,在UIApplicationDelegate:applicationWillTerminate,我删除了标志文件。或者,如果所有下载请求均未提交到iOS,则没有标志文件。然后,在应用程序重新启动时,通过UIApplicationDelegate:handleEventsForBackgroundURLSession,我检查是否有标志文件。如果丢失,那么我可以假定用户已终止。这里有两个选择。选择1:我不会重新创建URL会话。接下来发生的事情是iOS将在约20秒内终止我的应用程序。我不知道这(==不创建URL会话)是否合法,但是可以正常工作。用户可以在20秒内启动w /,因此我放置了更多代码来处理这种情况。选择2:我创建URL会话。接下来发生的事情是iOS调用了委托方法didFinishDownlaodingTo / didCompleteWithError,然后调用urlSessionDidFinishEvents。如果我在这里什么都没做,则该进程(app)会无限期地保持 Activity 状态,而不会向用户发送任何通知:任务切换器中没有任何操作。这无非是浪费内存。这里的选项是触发本地通知,并让用户知道我的应用程序,以便他们可以返回我的应用程序并可以终止(再次!),尽管我的应用程序显然显示为僵尸。两种选择都存在一个问题:在某些情况下,可能不会调用applicationWillTerminate(尽管我已经确认)。在这种情况下,标记文件保留为常规操作,并向用户显示僵尸。因此,标志文件方法只是缓解该问题的方法,但我认为它在大多数时间对我的应用程序都有效。
请注意,有时该应用会在被xcode调试器杀死或被带错误的操作系统(SEGFALUT)杀死时重新启动。
(4)观察:在应用终止(由用户等)然后由OS重新启动之后,该应用有时处于 Activity 状态(UIApplication.shared.applicationState为.active)。
我想通过本地通知在下载完成时通知用户,但是由于它处于 Activity 状态,因此不会触发本地通知。因此,我需要改用UIAlertController。因此,我无法提供一致的用户体验,并且对用户来说应该看起来很奇怪:大多数情况下是本地通知,偶尔还有UIAlert。请注意,当应用程序以 Activity 状态启动时,它会出现在任务切换器中。
猜猜:完全不知道如何发生。一件好事?这只是偶尔发生。
解决方法:似乎没有。
(5)观察:handleEventsForBackgroundURLSession / urlSessionDidFinishEvents仅被调用一次。
我在启动后台任务(application.beginBackgroundTask)之后开始下载。然后,在beginBackgroundTask的到期处理程序中,我将调用endBackgroundTask。我不知道为什么,但是在endBackgroundTask之后,我的进程仍然有很多处理时间,因此我可以继续请求下载。这可能是因为下载文件始终与didFinishDownlaodingTo一起出现。为了成为一个好公民,我暂停请求进一步下载,并向用户发出本地通知以将应用程序置于前台。现在,一旦我暂停请求,在4-5秒钟内,操作系统将确定URL会话已结束,并处理handleEventsForBackgroundURLSession,然后调用urlSessionDidFinishEvents。这是一次性事件。当用户将应用置于前台以恢复下载,然后再次置于后台时,不再会出现handleEventsForBackgroundURLSession / urlSessionDidFinishEvents。我不清楚会话的开始和结束的定义。会话似乎首先从URLSessionTask.resume()开始,然后以超时结束,这似乎由Apple’s document决定。但是,在此处设置大数字(1000秒)不会产生任何影响,它始终为4-5秒。
猜猜:不知道
解决方法:在应用程序运行时不要在urlSessionDidFinishEvents上进行中继。仅在操作系统重新启动应用程序时以及在初始handleEventsForBackgroundURLSession / urlSessionDidFinishEvents时进行中继。
===============
在下面,我列出了URLSessionConfiguration.timeoutIntervalForRequest(downLoader.zip)。您可以使用示例验证以上所有内容。
关于ios - NSURLSessionDownloadTask移动临时文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45338412/
我在使用 NSURLSessionDownloadTask 处理 ios 上的“空间不足”/“磁盘已满”错误时遇到问题 如果由于应用程序中完成下载而导致磁盘已满,我会接到电话 URLSession(
我使用NSURLSessionDownloadTask从服务器下载文件,该文件在后台 session 中运行。我想保存恢复数据以在应用终止时恢复下载。但是,对cancelByProducingResu
我有一个主机应用程序,它有一个完美运行的后台下载 session ,但是通过今天的扩展启动下载我得到这个错误: The operation couldn’t be completed. (NSURLE
我是 NSURLSession 的新手,我没有在其他 stackoverflow 问题中找到答案。所以我发布这个。 我的 ViewController 中有一个 Button 和 ProgressBa
我有以下一段代码,它已经工作了几个月,并且刚刚开始间歇性地损坏。 我正在改变它被调用的方式,所以这并不完全不足为奇,但症状让我感到困惑。某些请求正在下载的临时文件似乎在读取数据之前被删除。 我有关于文
我正在使用 NSURLSessionDownloadTask 下载文件。在应用程序的某一时刻,有必要暂停下载一小段时间,然后再继续下载。我尝试使用暂停方法暂停下载,但任务继续下载。 NSURLSess
有人可以帮我把这个语句翻译成 Swift 吗? NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:request
使用 NSURLSessionDownloadTask 连续下载文件列表的最佳做法是什么? 例如,是否最好在上一次下载完成后开始一个新的 NSURLSession? - (void)startDown
我需要按顺序下载文件。目前我可以在应用程序处于前台时执行此操作。 以下是我使用的逻辑。 创建所有下载任务。 一次恢复一个,当前完成后从 URLSession:task:didCompleteWithE
我正在使用 nsurlsession 来管理下载图像/视频文件。问题是有时请求会出错并返回“找不到内容”之类的文本。我如何确保正在下载的文件确实是我请求的文件类型? (例如 .jpeg 或 .mp4)
我添加“下载任务”并终止应用进程。 运行app后,获取[manager downloadTasks];并恢复所有。但文件未加载到 Documets 目录中。 我使用 AFNetworking 2.0
这就是我使用 NSURLSessionDownloadTask 的方式: let sessionConfiguration = NSURLSessionConfiguration.defaul
我的 iOS 应用程序使用 NSURLSessionConfiguration、NSURLSession、NSURLSessionDownloadTask 等来下载我们的服务器从数据库中动态生成的 x
我想知道我是否可以检索失败的 NSURLSessionDownloadTask 的部分下载数据。 我的用例是: 我开始下载一个 1024MB 的文件 已下载 512MB 网络中断下载失败 下载失败时,
我需要使用桌面应用程序下载文件。首先,我创建了一个简单的iOS项目,用于下载视频文件,引用这个web site 。有用。我想为 macOS 做几乎同样的事情。 class ViewController
我正在使用 NSURLSessionDownloadTask 下载网页文件。当我使用 [NSURLSessionConfiguration backgroundSessionConfiguration
我正在尝试使用 NSURLSessionDownloadTask 下载一个大文件。但是,我只想下载该文件的前 10MB。我知道如何在下载 10MB 后取消操作,但如何强制调用 didFinishDow
在我的应用程序中,我从 Web 服务获取 JSON。此 JSON 包含我要下载的几个文件的网址。 我想使用 NSURLSessionDownloadTask 一个一个地下载每个文件(等待第一个下载完成
我需要从服务器下载一些图片和一段视频: NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSes
在我的应用程序中,我目前正在使用 NSURLSessionDownloadTask通过 HTTP 获取文件。 此类提供了一个有用的委托(delegate)接口(interface)来监控其进度并在通过
我是一名优秀的程序员,十分优秀!