Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my URLDownloadTask not call didFinishDownloadtingTo?

Most of my programming experience is in Shell and Python. I'm fairly new to Swift, like "3 days ago" new. I just can't figure out why didFinishDownloadtingTo is not called when my downloadTask completes. Here's my AppDelegate.swift file:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, URLSessionDelegate, URLSessionDownloadDelegate {

@IBOutlet weak var window: NSWindow!
@IBOutlet var progressind: NSProgressIndicator!
@IBOutlet var outputtext: NSTextField!



func applicationDidFinishLaunching(_ aNotification: Notification) {

    // Insert code here to initialize your application
    let requestURL: URL = URL(string: "https://www.apple.com")!
    let urlRequest: URLRequest = URLRequest(url: requestURL as URL)
    let session = URLSession.shared
    let downloads = session.downloadTask(with: urlRequest)
    print("starting download...")
    downloads.resume()

}

func applicationWillTerminate(_ aNotification: Notification) {
    // Insert code here to tear down your application
}

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL){
    print("download finished!")
}


}

I'm using Swift 3, and I just cannot find enough documentation on it to figure this out on my own.

I went a little crazy declaring classes trying to figure out why it wasn't working right, so I'm sure there are also some errors there.

It appears to download the file successfully. I've tried with several URLs. The "Disk" and "Network" sections of the debug menu appear consistent with downloading a file of the size at every URL I've tested with.

like image 920
Matt Avatar asked Dec 24 '22 02:12

Matt


1 Answers

The thing is that when you use NSURLSession(URLSession in Swift 3) you have to choose if you want to use a delegate or a completion handler, in case of use both, only the completion handler gets called. In your case the delegate is not set so you can't see the call to the delegate methods. Instead you should specify the delegate using the another initializer of NSURLSession like in the following code:

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, URLSessionDelegate, URLSessionDownloadDelegate {

   func applicationDidFinishLaunching(_ aNotification: Notification) {
      let requestURL: URL = URL(string: "https://www.apple.com")!
      let urlRequest: URLRequest = URLRequest(url: requestURL as URL)

      let config = URLSessionConfiguration.default
      let session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)

      let downloads = session.downloadTask(with: urlRequest)

      print("starting download...")
      downloads.resume()
   }

   func applicationWillTerminate(_ aNotification: Notification) {
      // Insert code here to tear down your application
   }

   func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL){
       print("download finished!")
   }   
}

And then you should see the delegate method called properly.

I hope this help you

like image 138
Victor Sigler Avatar answered Mar 03 '23 19:03

Victor Sigler