Urlsessiondelegate's Didwritedata Not Call When App Is Going to Background in iOS12

URLSession delegates not working after app resume

Finally found a workaround for the issue. Once the application did return from background mode, make sure to call resume on all running tasks. This seems to reactivate callbacks to the delegate.

func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
DownloadManager.shared.session.getAllTasks(completionHandler: { tasks in
for task in tasks {
task.resume()
}
})

}

For more information on this topic, Follow this link:
https://forums.developer.apple.com/thread/77666

NSURLSessionTask never calls back after timeout when using background configuration

Since iOS8, the NSUrlSession in background mode does not call this delegate method if the server does not respond.
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
The download/upload remains idle indefinitely.
This delegate is called on iOS7 with an error when the server does not respond.

In general, an NSURLSession background session does not fail a task if
something goes wrong on the wire. Rather, it continues looking for a
good time to run the request and retries at that time. This continues
until the resource timeout expires (that is, the value of the
timeoutIntervalForResource property in the NSURLSessionConfiguration
object you use to create the session). The current default for that
value is one week!

Quoted information taken from this Source

In other words, the behaviour of failing for a timeout in iOS7 was incorrect. In the context of a background session, it is more interesting to not fail immediately because of network problems. So since iOS8, NSURLSession task continues even if it encounters timeouts and network loss. It continues however until timeoutIntervalForResource is reached.

So basically timeoutIntervalForRequest won't work in Background session but timeoutIntervalForResource will.

Swift: How to catch disk full error on background URLSession.downloadTask?

I had to solve this problem for my company not that long ago. Now my solution is in Objective C so you'll have to convert it over to Swift, which shouldn't be that hard. I created a method that got the available storage space left on the device and then checked that against the size of the file we're downloading. My solution assumes you know the size of the file you download, in your case you can use the totalBytesExpectedToWrite parameter in the didWriteData method.

Here's what I did:

+ (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;
}

Make sure you leave some room for error with these numbers, since iTunes, the settings app on the device, and this number never match up. The number we get here is the smallest of the three and is in MB. I hope this helps and let me know if you need help converting it to Swift.

URLSession downloadTask behavior when running in the background?

Your problem is that you are creating a new session every time you reference the session variable:

var session : URLSession {
get {
let config = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).background")
return URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue())
}
}

Instead, keep the session as an instance variable, and just get it:

class DownloadManager:NSObject {

static var shared = DownloadManager()
var delegate = DownloadManagerSessionDelegate()
var session:URLSession

let config = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).background")

override init() {
session = URLSession(configuration: config, delegate: delegate, delegateQueue: OperationQueue())
super.init()
}
}

class DownloadManagerSessionDelegate: NSObject, URLSessionDelegate {
// implement here
}

When I do this in a playground, it shows that repeated calls give the same session, and no error:

playground

The session doesn't live in-process, it's part of the OS. You're incrementing reference count every time you access your session variable as written, which causes the error.

Swift background download task got suspended when I application goes into background

You need to configure the background tasks to make that work properly.

For more details to configure background tasks please check this official apple developer documentation

https://developer.apple.com/documentation/foundation/url_loading_system/downloading_files_in_the_background



Related Topics



Leave a reply



Submit