Swift: 如何在后台捕获磁盘已满错误 URLSession.downloadTask?
Swift: How to catch disk full error on background URLSession.downloadTask?
我很难理解我认为容易的东西。
我有一个URLSession.downloadTask。我已将我的下载对象设置为 URLSession 委托,并且以下委托方法会接收调用,因此我知道我的委托设置正确。
func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?)
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)
我无法捕获的情况是当 downloadTask 在 iPad 上填满磁盘 space 时。 None 的委托方法被调用。
我应该如何捕捉这个错误?
这是我的下载对象:
import Foundation
import Zip
import SwiftyUserDefaults
extension DownloadArchiveTask: URLSessionDownloadDelegate {
// Updates progress info
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask,
didWriteData bytesWritten: Int64, totalBytesWritten: Int64,
totalBytesExpectedToWrite: Int64) {
let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
self.delegate?.updateProgress(param: progress)
}
// Stores downloaded file
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
print("DownloadArchiveTask: In didFinishDownloadingTo")
}
}
extension DownloadArchiveTask: URLSessionTaskDelegate {
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
print("DownloadArchiveTask: In didCompleteWithError")
if error != nil {
print("DownloadArchiveTask: has error")
self.delegate?.hasDiskSpaceIssue()
}
}
}
extension DownloadArchiveTask: URLSessionDelegate {
// Background task handling
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
print("DownloadArchiveTask: In handler for downloading archive")
DispatchQueue.main.async {
let sessionIdentifier = session.configuration.identifier
if let sessionId = sessionIdentifier, let app = UIApplication.shared.delegate as? AppDelegate, let handler = app.completionHandlers.removeValue(forKey: sessionId) {
handler()
}
}
}
func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) {
print("DownloadArchiveTask: didBecomeInvalidWithError")
if error != nil {
print("DownloadArchiveTask: has error")
self.delegate?.hasDiskSpaceIssue()
}
}
}
class DownloadArchiveTask: NSObject {
var delegate: UIProgressDelegate?
var archiveUrl:String = "http://someurl.com/archive.zip"
var task: URLSessionDownloadTask?
static var shared = DownloadArchiveTask()
// Create downloadsSession here, to set self as delegate
lazy var session: URLSession = {
let configuration = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).background_archive")
return URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
}()
func initialDownload() {
// Create URL to the source file you want to download
let fileURL = URL(string: archiveUrl)
let request = URLRequest(url:fileURL!)
self.task = self.session.downloadTask(with: request)
task?.resume()
}
}
有人做过吗?真不敢相信这么难 - 我一定是以错误的方式解决问题...
不久前我不得不为我的公司解决这个问题。现在我的解决方案在 Objective C 中,因此您必须将其转换为 Swift,这应该不难。我创建了一个方法来获取设备上剩余的可用存储空间 space,然后根据我们正在下载的文件的大小进行检查。我的解决方案假设您知道下载文件的大小,在您的情况下,您可以在 didWriteData
方法中使用 totalBytesExpectedToWrite
参数。
这是我所做的:
+ (unsigned long long)availableStorage
{
unsigned long long totalFreeSpace = 0;
NSError* error = nil;
NSArray* paths = NSSearchPathForDirectoriesInDomain(NSDocumentDirectory, NSUserDomainMask, YES);
NSDictionary* dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error:&error];
if (dictionary)
{
NSNumber* freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue];
}
return totalFreeSpace;
}
请确保为这些数字留出一些错误空间,因为 iTunes、设备上的设置应用程序和此数字永远不会匹配。我们在这里得到的数字是三者中最小的,以 MB 为单位。我希望这对您有所帮助,如果您需要帮助将其转换为 Swift.
,请告诉我
我很难理解我认为容易的东西。
我有一个URLSession.downloadTask。我已将我的下载对象设置为 URLSession 委托,并且以下委托方法会接收调用,因此我知道我的委托设置正确。
func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?)
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)
我无法捕获的情况是当 downloadTask 在 iPad 上填满磁盘 space 时。 None 的委托方法被调用。
我应该如何捕捉这个错误?
这是我的下载对象:
import Foundation
import Zip
import SwiftyUserDefaults
extension DownloadArchiveTask: URLSessionDownloadDelegate {
// Updates progress info
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask,
didWriteData bytesWritten: Int64, totalBytesWritten: Int64,
totalBytesExpectedToWrite: Int64) {
let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
self.delegate?.updateProgress(param: progress)
}
// Stores downloaded file
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
print("DownloadArchiveTask: In didFinishDownloadingTo")
}
}
extension DownloadArchiveTask: URLSessionTaskDelegate {
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
print("DownloadArchiveTask: In didCompleteWithError")
if error != nil {
print("DownloadArchiveTask: has error")
self.delegate?.hasDiskSpaceIssue()
}
}
}
extension DownloadArchiveTask: URLSessionDelegate {
// Background task handling
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
print("DownloadArchiveTask: In handler for downloading archive")
DispatchQueue.main.async {
let sessionIdentifier = session.configuration.identifier
if let sessionId = sessionIdentifier, let app = UIApplication.shared.delegate as? AppDelegate, let handler = app.completionHandlers.removeValue(forKey: sessionId) {
handler()
}
}
}
func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) {
print("DownloadArchiveTask: didBecomeInvalidWithError")
if error != nil {
print("DownloadArchiveTask: has error")
self.delegate?.hasDiskSpaceIssue()
}
}
}
class DownloadArchiveTask: NSObject {
var delegate: UIProgressDelegate?
var archiveUrl:String = "http://someurl.com/archive.zip"
var task: URLSessionDownloadTask?
static var shared = DownloadArchiveTask()
// Create downloadsSession here, to set self as delegate
lazy var session: URLSession = {
let configuration = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).background_archive")
return URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
}()
func initialDownload() {
// Create URL to the source file you want to download
let fileURL = URL(string: archiveUrl)
let request = URLRequest(url:fileURL!)
self.task = self.session.downloadTask(with: request)
task?.resume()
}
}
有人做过吗?真不敢相信这么难 - 我一定是以错误的方式解决问题...
不久前我不得不为我的公司解决这个问题。现在我的解决方案在 Objective C 中,因此您必须将其转换为 Swift,这应该不难。我创建了一个方法来获取设备上剩余的可用存储空间 space,然后根据我们正在下载的文件的大小进行检查。我的解决方案假设您知道下载文件的大小,在您的情况下,您可以在 didWriteData
方法中使用 totalBytesExpectedToWrite
参数。
这是我所做的:
+ (unsigned long long)availableStorage
{
unsigned long long totalFreeSpace = 0;
NSError* error = nil;
NSArray* paths = NSSearchPathForDirectoriesInDomain(NSDocumentDirectory, NSUserDomainMask, YES);
NSDictionary* dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error:&error];
if (dictionary)
{
NSNumber* freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue];
}
return totalFreeSpace;
}
请确保为这些数字留出一些错误空间,因为 iTunes、设备上的设置应用程序和此数字永远不会匹配。我们在这里得到的数字是三者中最小的,以 MB 为单位。我希望这对您有所帮助,如果您需要帮助将其转换为 Swift.
,请告诉我