Search code examples
swiftnsurlconnectionnsurlrequest

Download Multiple File at a time in Swift


I was finally able to download 1 video from a server using the following code:

    import UIKit

    class ViewController: UIViewController, NSURLConnectionDelegate {


    var file:NSFileHandle?

    @IBOutlet weak var webView: UIWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        downloadVideo()
    }





    func downloadVideo(sender: UIButton) {

        let urlPath: String = "http://www.ebookfrenzy.com/ios_book/movie/movie.mov"
        var url: NSURL = NSURL(string: urlPath)!
        var request: NSURLRequest = NSURLRequest(URL: url)
        var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: true)!
        connection.start()

    }


    func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {


        var fileName = "test.mov"

        var fileAtPath = fileInDocumentsDirectory(fileName)
        if(NSFileManager.defaultManager().fileExistsAtPath(fileAtPath) == false)
        {
            NSFileManager.defaultManager().createFileAtPath(fileAtPath, contents: nil, attributes: nil)
        }

         file = NSFileHandle(forWritingAtPath: fileAtPath)!

        if ((file) != nil){
              file!.seekToEndOfFile()
         }


    }

    func connection(connection: NSURLConnection!, didReceiveData data: NSData!){

        //write,each,data,received
        if(data != nil){


           if((file) != nil){

            file!.seekToEndOfFile()

            }

          file!.writeData(data)


        }


    }

    func connectionDidFinishLoading(connection: NSURLConnection!) {

         file!.closeFile()
    }



    func documentsDirectory() -> String {

        let documentsFolderPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as String

        return documentsFolderPath
    }


    func fileInDocumentsDirectory(filename: String) -> String{
    return documentsDirectory().stringByAppendingPathComponent(filename)
    }



    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

But I need to download a lot of video files(I have at least 100 URL), how can I do it? I was thinking of doing it one at a time but I guess that in that approach I will have a lot of NSURLConnections instances and maybe I will eat all my RAM, Can you please help me to learn the right form of multiple files download?

Thank you so much!


Solution

  • You can use a concurrent queue to limit the max number of connections at a time.

    func downloadVideo(sender: UIButton) {
        for urlPath in urlPaths {
            dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)) {
                var url: NSURL = NSURL(string: urlPath)!
                var request: NSURLRequest = NSURLRequest(URL: url)
                var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: true)!
                connection.start()
            }
        }
    }
    

    If you want to customize the max number of connections, check here: Can I limit concurrent requests using GCD?