1

URLSessionDownloadTask当应用程序处于关闭状态或我的下载状态发生更改时,我想保存核心数据,例如从等待状态变为下载状态或完成状态。

我的自定义类的所有其他属性都存储得很好,但是应用程序在存储下载任务时会崩溃。

崩溃的原因是

[__NSCFLocalDownloadTask encodeWithCoder:]:无法识别的选择器发送到实例 0x7ff189f181c0 -[NSKeyedArchiver dealloc]:警告:NSKeyedArchiver 在没有调用 -finishEncoding 的情况下被释放。由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[__NSCFLocalDownloadTask encodeWithCoder:]:无法识别的选择器发送到实例 0x7ff189f181c0”

这是我的课

class VideoDownloadModel : NSManagedObject {

    @NSManaged var videoID : NSNumber?
    @NSManaged var vid : Video?
    @NSManaged var downloadTask : URLSessionDownloadTask?
    @NSManaged var downloadStatus : String?
}

像这样存储它

    let request = NSFetchRequest<NSFetchRequestResult>(entityName: (COREDATA_ENTITY_Description?.name)!)
    request.returnsObjectsAsFaults = false
    request.predicate = NSPredicate(format: "videoID == %@", videoModel.videoID!)

        do {
            let result = try COREDATA_CONTEXT.fetch(request)
            print(result)
            var vidArr = result as! [VideoDownloadModel]

            if vidArr.count != 0 {
                vidArr[0] = videoModel

                COREDATA_MANAGER.saveContext()
            }

        } catch {
            let fetchError = error as NSError
            print(fetchError)
        }

什么时候URLSessionDownlaodTask可以nil正常工作,但是当任何下载开始时,它会在保存时崩溃。

场景:

  • 我用所有属性初始化了我的自定义类对象,但将任务设置为 nil。

  • 我将该对象存储在它完美保存的核心数据中。

  • 我初始化该对象的任务,下载工作完美。

  • 然后我更新核心数据中的对象,同时更新应用程序崩溃了,因为 URLSssionTask 没有从 NSCoding 继承。所以它没有编码和解码方法。

我想要一些解决方案来解决这个问题

任何帮助将不胜感激。谢谢。

4

2 回答 2

1

您无法保存URLSessionDownloadTask在 Core Data 中,因为 - 正如您所提到的 - 它不符合NSCoding. 在许多情况下,答案是编写您自己的代码来转换/转换,Data但在这种情况下不起作用。AURLSessionDownloadTask只能由 a 创建URLSession,因此不能序列化和反序列化任务对象。

不过这并不重要,因为保存和恢复它们没有意义。AURLSessionDownloadTask代表应用程序运行时正在进行的操作。如果您的应用程序已关闭,则该活动结束。在应用程序关闭并重新启动后恢复 aURLSessionDownloadTask没有意义,因为它没有可以表示的活动。基本上,即使您可以存储任务对象并对其进行恢复,恢复后也将毫无用处。没有理由打扰。

如果您的兴趣是要恢复不完整的下载,则必须从头开始。创建你的URLSession然后用它来创建一个新的URLSessionDownloadTask. 如果您有兴趣获取有关后台下载的信息,则可以使用会话对象getTasksWithCompletionHandler(_:)来确定它们是否已完成。

于 2017-06-02T17:46:46.183 回答
0

储蓄URLSessionDownloadTask没有意义。您实际上希望downloadTask.cancel(byProducingResumeData: )在暂停时保存从中获得的数据。

一旦您需要恢复下载,请使用downloadTaskWithResumeData(:)和恢复使用保存的数据创建一个新的下载任务。

应用终止时 - 不包括应用被用户强行终止的情况。

URLSession 上的苹果文档清楚地解释了应用程序终止时要做什么。
来自文档 -在 iOS 和 OS X 中,当用户重新启动您的应用程序时,您的应用程序应立即创建具有与您的应用程序上次运行时具有未完成任务的任何会话相同的标识符的后台配置对象,然后为每个会话创建一个会话这些配置对象。这些新会话同样会自动与正在进行的后台活动重新关联。

当用户强行终止应用程序时

urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)在这种情况下,将触发URLSession 委托,其中对象中的userInfodicterror将具有与 key 对应的恢复数据NSURLSessionDownloadTaskResumeData,可用于使用 恢复任务downloadTask.cancel(byProducingResumeData: )。另请注意,您必须进行类型转换error才能NSError检索userInfo字典。

在使用之前阅读这里的文档会很好NSURLSession

于 2017-10-12T09:16:56.817 回答