Can't able to catch error when turn off network connection at the time of downloading a file

Viewed 149

I am trying to download .mp3 file from server using using URLSession. It also works in background. Here is the variables i have declared.

var urlSession: URLSession?
var sessionTask: URLSessionDownloadTask?
var resumeData: Data?

This is how i initialised the URLSession.

let config = URLSessionConfiguration.background(withIdentifier: "com.example.app.background")
config.networkServiceType = .background
urlSession = URLSession(configuration: config, delegate: self, delegateQueue: nil)

To download i am using URLSessionDownloadTask. I have also implemented pause/resume functionality. Here is the code.

func startDownload(with url: String) {
    sessionTask = urlSession?.downloadTask(with: URL(string: url)!)
    sessionTask?.resume()
}

func cancelDownload() {
    sessionTask?.cancel()
}

func pauseDownload() {
    sessionTask?.cancel(byProducingResumeData: { (data) in
        self.resumeData = data
    })
}

func resumeDownload(url: String) {
    if let resumeData = self.resumeData {
        sessionTask = urlSession?.downloadTask(withResumeData: resumeData)
    } else {
        sessionTask = urlSession?.downloadTask(with: URL(string: url)!)
    }
    sessionTask?.resume()
}

As i have enabled download in background, to receive success, failure and progress of download i have confirmed URLSessionDownloadDelegate methods.

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)

Everything seems fine when i download a file even in background. I have got the success, failure and progress of the download in delegate methods.

But the problem is if i turn off network connection at the middle of downloading a file, i get some error logs in console. But none of the above delegate methods are called. Here is the logs

Task <0B34AE9E-0A46-4E78-8C90-7353CDC34929>.<10> finished with error [-1020] Error Domain=NSURLErrorDomain Code=-1020 "A data connection is not currently allowed." UserInfo={_kCFStreamErrorCodeKey=50, NSUnderlyingError=0x2817b40c0 {Error Domain=kCFErrorDomainCFNetwork Code=-1020 "(null)" UserInfo={_kCFStreamErrorCodeKey=50, _kCFStreamErrorDomainKey=1}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <0B34AE9E-0A46-4E78-8C90-7353CDC34929>.<10>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <0B34AE9E-0A46-4E78-8C90-7353CDC34929>.<10>"
), NSLocalizedDescription=A data connection is not currently allowed.

How can i get the error response to show the user that you have lost your network connection?

I have searched for it but didn't find the solution. Pardon me if it's a duplicate question. Thanks.

1 Answers

To get the error returned, you need to use the alternative functions of downloadTask that have a completionHandler`

self.urlSsn?.downloadTask(with: MyURLRequest, completionHandler: { data, response, error -> Void in
    if let error = error {
        print("\(error.localizedDescription)")
        // This should print "A data connection is not currently allowed."
    }
}

A similar is available for downloadTask(withResumeData) as well.

If you want to compare specific error codes (as error code -1020 in your example). You can do the following:

if let error = error {
    let e = error! as NSError
    switch e.code {
    case NSURLErrorNotConnectedToInternet:
        print("No internet")
    default:
        print("Some other error")
    }
}

More info here and here

Related