tus / TUSKit

The tus client for iOS.
https://tus.io/
MIT License
209 stars 114 forks source link

Upload failed if app is running in the background #57

Closed deeplinkage closed 2 years ago

deeplinkage commented 4 years ago

I'm using the official example for Tus iOS, uploading a file of approx. 50MB to the Tus test server. If the app is running on the screen the upload is successful.

When I start the upload after few seconds I put the app in the background, and it seems to be working for the next 15-20 seconds then it returns the error:

2019-11-27 10:57:25.797502+0100 TUSKit[22159:529437] Task <61AC3E82-19C2-411F-BDF5-427499B7A96A>.<2> finished with error [-999] Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLStringKey=http://master.tus.io/files/0b58c6f6c83f7aea04d77deff5099da7+9MHwWbvMSpEPD6j4irvGAZWTPHmEqdg2D6dbOGdxzSz6rINoGB0Sb0uI3WreyL8mqHBOzLOrBpD0Oz.xilW2OHq_PvHCW3q6ToW6Tz9kaYFFu_jl.zFZyP.eLkEA.9P., NSLocalizedDescription=cancelled, NSErrorFailingURLKey=http://master.tus.io/files/0b58c6f6c83f7aea04d77deff5099da7+9MHwWbvMSpEPD6j4irvGAZWTPHmEqdg2D6dbOGdxzSz6rINoGB0Sb0uI3WreyL8mqHBOzLOrBpD0Oz.xilW2OHq_PvHCW3q6ToW6Tz9kaYFFu_jl.zFZyP.eLkEA.9P.} 2019-11-27 10:57:25.797764+0100 TUSKit[22159:529437] <TUSResumableUpload.m:(585)> Error or no response during attempt to upload file, checking state

MMasterson commented 4 years ago

Hey @deeplinkage

iOS’s watchdog cuts off background processes after about 20 seconds. There are a few ways around this for now since the SDK/docs need a bit of an update for direct support, if you can wait till tomorrow night I can get a better example, otherwise here are a few helpful links. Just wanted to reply since I saw this came in a few minutes ago

https://www.spaceotechnologies.com/ios-background-task-framework-app-update/

https://medium.com/swlh/handling-background-tasks-in-ios-13-67f717d94b3d

https://medium.com/snowdog-labs/managing-background-tasks-with-new-task-scheduler-in-ios-13-aaabdac0d95b

deeplinkage commented 4 years ago

Thanks @MMasterson for a quick reply. I thought TusKit is using NSURLSession inside TUSSession in order to support uploads in the background. When you get time if you can provide more details that would be awesome in the meantime I will check the links you provided.

deeplinkage commented 4 years ago

Hi @MMasterson, did you had a chance to take a look at the better example? Is this iOS 13 only issues, since the links you sent are only for iOS 13. Thanks again for your time.

deeplinkage commented 4 years ago

Hi @MMasterson did you had a chance to take a look? I need to see If I can make this work since we upload videos so we need background upload capability. Thanks in advance.

MMasterson commented 4 years ago

hey @deeplinkage

This is not just an iOS13 issue, it's an overall iOS issue. A common work around is enabling location services and ask for location updates in the background. And when func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) is hit, run a resume.

If you have any ideas on how you'd better like this to function it'd be great to hear your input

Did you take a look at any of the other discussions in the issues?

deeplinkage commented 4 years ago

hi @MMasterson,

I think my problem is I cannot make a background session and pass it to TUSSession. See below:

let sessionConfiguration = URLSessionConfiguration.background(withIdentifier: "identifierForBackg")

let tusSession = TUSSession(endpoint: URL(string: fileUploadUrl)!, dataStore: self.uploadStore!, sessionConfiguration: sessionConfiguration)

let upload = tusSession.createUpload(fromFile: URL(string: documentsFilePath)!, retry: 3, headers: header, metadata: metadata)

If I do this I get error:

Terminating app due to uncaught exception 'NSGenericException', reason: 'Completion handler blocks are not supported in background sessions. Use a delegate instead.'

deeplinkage commented 4 years ago

BTW - If l add location manager with regular session it works. This is just a problem if apple review would pass and if our users tap to not allow location since they are strict about location using, they present user with several pop-ups - it would not work. 

MMasterson commented 4 years ago

hey @deeplinkage

Found an article that might help with a fix https://medium.com/livefront/uploading-data-in-the-background-in-ios-f93722013c6a

I'll try to implement something like this over the weekend. However, this does not fix the fact that iOS13+ kills background processes after about 20 seconds. The location hack is the only way I know to get around that.

foxware00 commented 4 years ago

hi @MMasterson,

I think my problem is I cannot make a background session and pass it to TUSSession. See below:

let sessionConfiguration = URLSessionConfiguration.background(withIdentifier: "identifierForBackg")

let tusSession = TUSSession(endpoint: URL(string: fileUploadUrl)!, dataStore: self.uploadStore!, sessionConfiguration: sessionConfiguration)

let upload = tusSession.createUpload(fromFile: URL(string: documentsFilePath)!, retry: 3, headers: header, metadata: metadata)

If I do this I get error:

Terminating app due to uncaught exception 'NSGenericException', reason: 'Completion handler blocks are not supported in background sessions. Use a delegate instead.'

I'm very interested in this, are we not allowed background session configurations? How can we handle uploads being triggered from a background service and picked up from the main app session?

@MMasterson is it by design that background sessions are not supported or is it just yet to be implemented?

I've been digging through the code and the choice to use the callbacks on the dataTask limit the application of the library somewhat. Migrating over to using the proper callback methods supported by background sessions would allow for it to be used within app extensions where they can hand off to the main app and grab the existing session to finish up work. Does this break what TUS is achieving a little? It's hard to understand the implications of migrating the library to delegates without understanding how it might affect current assumptions within the library

MMasterson commented 4 years ago

@foxware00 I'll be implementing some more background support in swift-development - including delegate methods

custom session configs will be able to be passed for more control over background sessions

hannojg commented 3 years ago

I think this will be fixed with the release of 2.1.0. However, it won't guarantee that everything in the queue will be uploaded while the app is in the background. To make sure that everything in the queue gets uploaded we could write a new background mode, which will upload the file not using data but write the chunks to files first, and uploads these chunk files using https://developer.apple.com/documentation/foundation/urlsession/1411550-uploadtask

r-a-o commented 3 years ago

I think this will be fixed with the release of 2.1.0.

Hi, is background upload support part of 2.1.0?

MMasterson commented 3 years ago

@r-a-o yes, it is supported in 2.1.0!

elvirion commented 2 years ago

I’m closing this issue because it has been inactive.