Tom Crews
Tom Crews

Reputation: 77

Swift 3: Handle Errors in URLSession Delegates

I need to know how to catch errors (interruptions, primarily) in a URLsession with delegates.

I have the following Swift function within a custom class, which downloads a small file to test download speeds:

func testSpeed() {

    Globals.shared.dlStartTime = Date()
    Globals.shared.DownComplete = false


    let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil)

    let task = session.downloadTask(with: url!)

    if Globals.shared.currentSSID == "" {
        Globals.shared.bandwidth = 0
        Globals.shared.DownComplete = true

        session.invalidateAndCancel()

        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ProcessFinished"), object: nil, userInfo: nil)

    } else {
        print("Running Task")
        task.resume()

    }
}

This class uses URLSessionDelegate and URLSessionDownloadDelegate. Here are the current delegates it calls:

public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
    Globals.shared.dlFileSize = (Double(totalBytesExpectedToWrite) * 8) / 1000
    let progress = (Double(totalBytesWritten) / Double(totalBytesExpectedToWrite)) * 100.0
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ProcessUpdating"), object: nil, userInfo: ["progress" : progress])
}

^ That one monitors download progress and uses NotificationCenter to send the progress back to the view controller.

public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
    print("Done")
    if Globals.shared.DownComplete == false {
        let elapsed = Double( Date().timeIntervalSince(Globals.shared.dlStartTime))
        Globals.shared.bandwidth = Int(Globals.shared.dlFileSize / elapsed)
        Globals.shared.DownComplete = true
        Globals.shared.dataUse! += (Globals.shared.dlFileSize! / 8000)
    }
    session.invalidateAndCancel()

    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ProcessFinished"), object: nil, userInfo: nil)
}

^ That one just calculates the speed once the download is finished, and sends the result to a global variable in another class. Unimportant.

As of now, when I test my application, interrupting the download just hangs the app, because it keeps waiting for the processFinished NC call, which obviously never comes.

Is there another delegate I should add to catch that interruption, or am I missing something more obvious?

Upvotes: 2

Views: 1528

Answers (1)

carlos21
carlos21

Reputation: 485

You can use urlSession:task:didCompleteWithError delegate method

enter image description here

Upvotes: 1

Related Questions