2016-02-19 15 views
6

Ich bin ein Video dank downloadTaskWithURL Herunterladen und ich spare es mit diesem Code zu meiner Galerie:Swift - Herunterladen von Videos mit 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() 
} 

es auf meinem Simulator perfekt funktioniert gut, aber auf meinem iPad des Das Video wird nicht gespeichert, auch wenn print("Video is saved!"); angezeigt wird. Haben Sie eine Idee warum?

Ich habe auch diese Nachricht in meiner Konsole erscheinen

Unable to create data from file (null)

+0

Die Dokumentation für die 'completionHandler 'Teil der" downloadTaskWithURL "-Methode sagt" Sie müssen diese Datei verschieben oder öffnen Sie es für das Lesen vor Ihrer FertigstellungHandler zurückkehrt ". Nun, du scheinst immer noch im Completion-Handler zu sein, aber vielleicht (und ich vermute hier) rufst du eine andere Methode ('performChanges') in deinem CompletionHandler auf. Könnten Sie vielleicht versuchen, die Datei an einen anderen Ort zu kopieren, bevor Sie 'performChanges' aufrufen? – pbodsk

+0

Ich bin relativ neu zu Swift, kannst du mir bitte ein Beispiel geben, wie das geht? –

+0

Sie benötigen eine 'sourceURL' vom Typ NSURL, das ist Ihre' location' dann benötigen Sie eine 'destinationURL' Sie könnten vielleicht die 'location' nehmen und etwas an sie anhängen, vielleicht' let destination = NSURL (fileURLWithPath: location.absoluteString + "_dest") '. Sobald Sie das haben, benötigen Sie einen 'Dateimanager' vom Typ' NSFileManager', wie zum Beispiel 'let filemanager = NSFileManager.defaultManager()'. Und dann können Sie die Datei verschieben, indem Sie 'fileManager.moveItemAtURL (location, toURL: destination)' sagen. Diese Methode "wirft", also müssen Sie das in ein "do ... try ... catch" umwandeln. Hoffnung, die Sinn macht – pbodsk

Antwort

17

Bitte überprüfen Sie Kommentare über den 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") 
    } 

} 
+0

Es funktioniert völlig gut, danke! :) Nur ein kleiner Nachteil: wenn ich einen Film herunterlade, lösche ich ihn, versuche dann, ihn erneut herunterzuladen, er sagt mir, dass "die Datei bereits in der Ziel-URL existiert". –

+0

Sie können diese Bedingung entfernen und unter einem neuen Namen speichern –

+0

@LeoDabus Können Sie mir bitte sagen, wie ich 'NSURLSessionDownloadDelegate' Methoden mit diesem Code verwenden kann? weil seine Methoden mit diesem Code nicht funktioniert haben? – ZAFAR007