The question is old, but still unanswered, so here is one workaround.
Some clarifications first
In general there is a property of URLSessionConfiguration
called waitsForConnectivity
which can be set to false
where URLSessionTask
will then directly fail on connection lost. However if true
then URLSessionTaskDelegate
will receive a callback on the urlSession(_:taskIsWaitingForConnectivity:)
method.
However
Background tasks such as DownloadTask
always wait for connectivity and ignore waitsForConnectivity
property of URLSessionConfiguration
. They also DON'T trigger urlSession(_:taskIsWaitingForConnectivity:)
callback, so there is no official way to listen for connectivity drop-out on download task.
Workaround
If you listening for the download progress you'll notice that a call to the method is done few times in a second. Therefore we can conclude that if the progress callback is not called for more than 5 seconds, then there could be a connectivity drop issue. So the workaround is to make additional property to the URLSessionDownloadDelegate
delegate and store the last update of the progress. Then have interval function to periodically check whether this property were not updated soon.
Something like:
class Downloader: NSObject, URLSessionTaskDelegate, URLSessionDownloadDelegate {
var lastUpdate: Date;
var downloadTask: URLSessionDownloadTask?;
public var session : URLSession {
get {
let config = URLSessionConfiguration.background(
withIdentifier: "\(Bundle.main.bundleIdentifier!).downloader");
config.isDiscretionary = true;
return URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue());
}
}
override init() {
self.lastUpdate = Date();
super.init();
}
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
// Handle download completition
// ...
}
func urlSession(
_ session: URLSession,
downloadTask: URLSessionDownloadTask,
didWriteData bytesWritten: Int64,
totalBytesWritten writ: Int64,
totalBytesExpectedToWrite exp: Int64)
{
let progress = 100 * writ / exp;
// Do something with the progress
// ...
self.lastUpdate = Date();
}
}
var downloader = Downloader();
let url = "http://...";
var request = URLRequest(url: URL(string: url)!);
currentWorker.downloadTask = downloader.session.downloadTask(with: request);
currentWorker.downloadTask!.resume();
// Schedule timer for every 5 secs
var timer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "CheckInternetDrop", userInfo: nil, repeats: true);
func CheckInternetDrop(){
let interval = Date().timeIntervalSinceDate(downloader.lastUpdate);
if (interval > 5) {
print("connection dropped");
}
}
Very simple example...