这个问题很老,但仍然没有答案,所以这里有一个解决方法。
先做一些澄清
一般URLSessionConfiguration 有一个属性称为waitsForConnectivity,可以设置为false,其中URLSessionTask 将在连接丢失时直接失败。但是,如果true 则URLSessionTaskDelegate 将收到urlSession(_:taskIsWaitingForConnectivity:) 方法的回调。
但是
DownloadTask 等后台任务始终等待连接并忽略URLSessionConfiguration 的waitsForConnectivity 属性。他们也不要触发urlSession(_:taskIsWaitingForConnectivity:)回调,所以没有官方的方法来监听下载任务的连接丢失。
解决方法
如果您监听下载进度,您会注意到对该方法的调用在一秒钟内完成了几次。因此,我们可以得出结论,如果超过 5 秒未调用进度回调,则可能存在连接中断问题。因此解决方法是为URLSessionDownloadDelegate 委托添加附加属性并存储进度的最后更新。然后有间隔函数定期检查这个属性是否没有很快更新。
类似:
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");
}
}
非常简单的例子...