Swift - Downloading video with downloadTaskWithURL

13,311

Please check comments through the code:

Xcode 8 • Swift 3

import UIKit
import Photos

class ViewController: UIViewController {

    func downloadVideoLinkAndCreateAsset(_ videoLink: String) {

        // use guard to make sure you have a valid url
        guard let videoURL = URL(string: videoLink) else { return }

        guard let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }

        // check if the file already exist at the destination folder if you don't want to download it twice
        if !FileManager.default.fileExists(atPath: documentsDirectoryURL.appendingPathComponent(videoURL.lastPathComponent).path) {

            // set up your download task
            URLSession.shared.downloadTask(with: videoURL) { (location, response, error) -> Void in

                // use guard to unwrap your optional url
                guard let location = location else { return }

                // create a deatination url with the server response suggested file name
                let destinationURL = documentsDirectoryURL.appendingPathComponent(response?.suggestedFilename ?? videoURL.lastPathComponent)

                do {

                    try FileManager.default.moveItem(at: location, to: destinationURL)

                    PHPhotoLibrary.requestAuthorization({ (authorizationStatus: PHAuthorizationStatus) -> Void in

                        // check if user authorized access photos for your app
                        if authorizationStatus == .authorized {
                            PHPhotoLibrary.shared().performChanges({
                                PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: destinationURL)}) { completed, error in
                                    if completed {
                                        print("Video asset created")
                                    } else {
                                        print(error)
                                    }
                            }
                        }
                    })

                } catch { print(error) }

            }.resume()

        } else {
            print("File already exists at destination url")
        }

    }

    override func viewDidLoad() {
        super.viewDidLoad()
        downloadVideoLinkAndCreateAsset("https://www.yourdomain.com/yourmovie.mp4")
    }

}
Share:
13,311
Melanie Journe
Author by

Melanie Journe

Updated on June 06, 2022

Comments

  • Melanie Journe
    Melanie Journe about 2 years

    I'm downloading a video thanks to downloadTaskWithURL and I'm saving it to my gallery with this code :

        func saveVideoBis(fileStringURL:String){
    
        print("saveVideoBis");
    
        let url = NSURL(string: fileStringURL);
        (NSURLSession.sharedSession().downloadTaskWithURL(url!) { (location:NSURL?, r:NSURLResponse?, e:NSError?) -> Void in
    
            let mgr = NSFileManager.defaultManager()
    
            let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0];
    
            print(documentsPath);
    
            let destination = NSURL(string: NSString(format: "%@/%@", documentsPath, url!.lastPathComponent!) as String);
    
            print(destination);
    
            try? mgr.moveItemAtPath(location!.path!, toPath: destination!.path!)
    
            PHPhotoLibrary.requestAuthorization({ (a:PHAuthorizationStatus) -> Void in
                PHPhotoLibrary.sharedPhotoLibrary().performChanges({
                    PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(destination!);
                    }) { completed, error in
                        if completed {
                            print(error);
                            print("Video is saved!");
                            self.sendNotification();
                        }
                }
            })
        }).resume()
    }
    

    It works perfectly fine on my simulator but on my iPad the video isn't saved even if the print("Video is saved!"); appears. Do you have any idea why ?

    I also have that message appearing in my console

    Unable to create data from file (null)

  • Melanie Journe
    Melanie Journe over 8 years
    It works perfectly fine thanks you ! :) Only one little downside : when I download a movie, then delete it, then try to download it again, it tells me that "the file already exists at destination url".
  • Leo Dabus
    Leo Dabus over 8 years
    You can remove that condition and save it with a new name
  • ZAFAR007
    ZAFAR007 over 7 years
    @LeoDabus Can you please tell me how i can use NSURLSessionDownloadDelegate methods with this code? because its methods did't works with this code?
  • JAHelia
    JAHelia almost 7 years
    is there a way to fetch that specific asset from the photos library after downloading and saving it ?
  • Vineesh TP
    Vineesh TP over 6 years
    @LeoDabus : I used same code to save a .m3u8 file. But, when try to save the file it getting error , ' The operation couldn’t be completed. (Cocoa error -1.)'
  • Rashid KC
    Rashid KC almost 6 years
    @LeoDabus how to download pdf in same way?
  • Leo Dabus
    Leo Dabus almost 6 years
  • Rashid KC
    Rashid KC almost 6 years
    @LeoDabus I need to save the downloaded pdf into the files folder. I tried the above answer. but it shows "no preview to show"
  • Leo Dabus
    Leo Dabus almost 6 years
    Maybe your link is not https. I can only guess It would be easier for you to open a new question and put your issue there
  • Chandan Jee
    Chandan Jee over 4 years
    which type of self.downloadTask?
  • Rahul Gusain
    Rahul Gusain over 4 years
    var downloadTask : URLSessionDownloadTask?
  • Fernando Ivan Perez Ruiz
    Fernando Ivan Perez Ruiz about 2 years
    How do you play the downloaded video?