I want to save URLSessionDownloadTask
in core data when app is gone in closed state or my download state is changed e.g from waiting state to downloading state or to completed state.
All other attributes of my custom class are stored perfectly but app crashes when it stores download task.
reason to crash is
[__NSCFLocalDownloadTask encodeWithCoder:]: unrecognized selector sent to instance 0x7ff189f181c0 -[NSKeyedArchiver dealloc]: warning: NSKeyedArchiver deallocated without having had -finishEncoding called on it. Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFLocalDownloadTask encodeWithCoder:]: unrecognized selector sent to instance 0x7ff189f181c0'
this is my class
class VideoDownloadModel : NSManagedObject {
@NSManaged var videoID : NSNumber?
@NSManaged var vid : Video?
@NSManaged var downloadTask : URLSessionDownloadTask?
@NSManaged var downloadStatus : String?
}
storing it like this
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)
}
when URLSessionDownlaodTask
is nil
it works fine but when any download is started it crashes on saving.
scenerio :
I initialized my custom class object with all attributes but set task to nil.
I store that object in core data it saved perfectly.
I initialize the task of that object the download work perfectly.
Then i update the object in core data while updating the app got crash because URLSssionTask is not inheriting from NSCoding. so it don't have encoding and decoding methods.
I want some solution to solve this issue
Any help will be appreciated. Thanks.
Saving
URLSessionDownloadTask
doesn't make sense. You would actually want to save the data obtained fromdownloadTask.cancel(byProducingResumeData: )
while pausing.Once you need to resume the download create a new downloadtask with the saved data by using
downloadTaskWithResumeData(:)
and resume.When app is terminated - dosen't include the case when the app is forcefully terminated by the user.
The apple documentation on URLSession clearly explains what to do when app is terminated.
From the docs - In both iOS and OS X, when the user relaunches your app, your app should immediately create background configuration objects with the same identifiers as any sessions that had outstanding tasks when your app was last running, then create a session for each of those configuration objects. These new sessions are similarly automatically reassociated with ongoing background activity.
When user forcefully terminate the app
In this case, URLSession delegate
urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
will be fired, in which theuserInfo
dict inerror
object will have the resume data corresponding to the keyNSURLSessionDownloadTaskResumeData
, which could be used to resume the task usingdownloadTask.cancel(byProducingResumeData: )
. Also please note that you will have to typecasterror
toNSError
to retrieve theuserInfo
dict.It would be good to read through the docs here before using
NSURLSession