商店URLSessionDownloadTask核心数据

问题描述:

我要救URLSessionDownloadTask核心数据时,应用程序消失在封闭状态或我的下载状态从待机状态到下载状态或完成状态e.g改变。商店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) 
     } 

URLSessionDownlaodTasknil它工作正常,但是当任何下载开始崩溃节约。

之情况:

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

  • 我存储对象的核心数据它完美地保存。

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

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

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

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

+0

请出示你这样做(代码)_how_前必读。 – shallowThought

+0

我已将它添加到我的帖子中,请检查它。 –

+0

我非常怀疑从Core Data中获取任务后会恢复任务。 – vadian

您无法将URLSessionDownloadTask保存在核心数据中,因为 - 正如您所述 - 它不符合NSCoding。在很多情况下,答案是编写自己的代码来转换为/从Data,但在这种情况下不起作用。 A URLSessionDownloadTask只能由URLSession创建,因此无法序列化和反序列化任务对象。

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

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

+0

感谢您的回答,但可以请你指导我如何在应用程序重新启动后继续下载吗? –

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

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

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

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

当用户强行终止该应用

在这种情况下,URLSession委托urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)将被发射,其中,所述userInfo字典中error对象将具有对应于该键NSURLSessionDownloadTaskResumeData恢复数据,这可能是用于使用downloadTask.cancel(byProducingResumeData:)恢复任务。另请注意,您必须输入errorNSError来检索userInfo字典。

这将是很好过的文档here使用NSURLSession

+0

是的你是对的,但如何处理downloadTask.cancel(byProducingResumeData:)无法完成的情况。例如,当用户强行退出应用程序? –

+0

对不起,迟到了。我已经更新了答案。看看是否有帮助(如果你还没有找到解决方案:D) – Mot