2016-02-19 14 views
6

sto download di un video grazie a downloadTaskWithURL e sto salvandolo alla mia galleria con questo codice:Swift - Scaricare video con downloadTaskWithURL

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() 
} 

Funziona perfettamente bene sul mio simulatore, ma sul mio iPad al il video non viene salvato anche se appare print("Video is saved!");. Hai qualche idea del perché?

Ho anche quel messaggio che appare nella mia console

Unable to create data from file (null)

+0

la documentazione per il 'completionHandler 'parte del metodo' downloadTaskWithURL' dice "Devi spostare questo file o aprirlo per la lettura prima che il tuo completamentoHandler ritorni". Ora, sembra che tu sia ancora all'interno del gestore di completamento in ogni momento, ma forse (e sto indovinando qui) stai chiamando un altro metodo ('performChanges') all'interno del tuo completamentoHandler sta facendo casino qualcosa. Potresti provare a copiare il file in un'altra posizione prima di chiamare 'performChanges'? – pbodsk

+0

Sono relativamente nuovo a Swift, puoi darmi un esempio di come farlo per favore? –

+0

Hai bisogno di un 'sourceURL' di tipo NSURL, questo è il tuo' posizione', quindi hai bisogno di un 'destinationURL' potresti prendere il' location' e aggiungere qualcosa ad esso, magari 'let destination = NSURL (fileURLWithPath: location.absoluteString + "_dest") '. Una volta che hai bisogno di un 'fileManager' di tipo' NSFileManager', in questo modo 'lascia fileManager = NSFileManager.defaultManager()'. E quindi sei pronto per spostare il file dicendo 'fileManager.moveItemAtURL (location, toURL: destination)'. Quel metodo "getta" quindi è necessario avvolgerlo in un "do ... try ... catch". Spero che abbia senso – pbodsk

risposta

17

Si prega di controllare i commenti attraverso il codice:

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") 
    } 

} 
+0

Funziona perfettamente bene grazie! :) Solo un piccolo inconveniente: quando scarico un film, lo cancello, poi provo a scaricarlo di nuovo, mi dice che "il file esiste già nell'URL di destinazione". –

+0

Puoi rimuovere questa condizione e salvarla con un nuovo nome –

+0

@LeoDabus Puoi dirmi come posso usare i metodi 'NSURLSessionDownloadDelegate' con questo codice? perché i suoi metodi non funzionano con questo codice? – ZAFAR007