2016-02-19 28 views
6

mam pobierania wideo dzięki downloadTaskWithURL a ja ratuję go do mojej galerii z tego kodu:Swift - Pobieranie filmów z 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() 
} 

to działa perfekcyjnie na moim symulatora ale na moim iPad wideo nie zostanie zapisane, nawet jeśli pojawi się print("Video is saved!");. Czy masz pojęcie, dlaczego?

ja też mam ten komunikat pojawiający się w moim konsoli

Unable to create data from file (null)

+0

w dokumentacji 'completionHandler 'część metody' downloadTaskWithURL' mówi: "Musisz przenieść ten plik lub otworzyć go do odczytu, zanim zakończy się returnHandler". Wygląda na to, że cały czas jesteś wewnątrz programu obsługi zakończenia, ale być może (i zgaduję, że tutaj) wywołujesz inną metodę ('performChanges') w swoim zakończeniuHandler coś zepsuje. Czy mógłbyś spróbować skopiować plik do innej lokalizacji, zanim zadzwonisz do 'performChanges'? – pbodsk

+0

Jestem względnie nowy w Swift. Czy możesz mi podać przykład tego, jak to zrobić? –

+0

Potrzebujesz 'sourceURL' typu NSURL, to jest twoja' lokalizacja' to potrzebujesz 'destinationURL' możesz wziąć' location' i dołączyć coś do niej, może 'let destination = NSURL (fileURLWithPath: location.absoluteString + "_dest") '. Kiedy już będziesz potrzebował 'fileManager' typu' NSFileManager', np. 'Let fileManager = NSFileManager.defaultManager()'. Następnie jesteś gotowy do przeniesienia pliku, mówiąc: 'fileManager.moveItemAtURL (location, toURL: destination)'. Ta metoda "wyrzuca", więc musisz ją zawijać w 'do ... try ... catch'. Nadzieja, że ​​ma sens – pbodsk

Odpowiedz

17

Proszę sprawdzić komentarze za pomocą kodu:

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

Działa idealnie dobrze dzięki! :) Tylko jeden mały minus: kiedy pobieram film, a potem go usuwam, a następnie spróbuj go pobrać ponownie, mówi mi, że "plik już istnieje w docelowym adresie URL". –

+0

Możesz usunąć ten warunek i zapisać go pod nową nazwą –

+0

@LeoDabus Czy możesz mi powiedzieć, jak mogę użyć metod 'NSURLSessionDownloadDelegate' z tym kodem? ponieważ jego metody nie działają z tym kodem? – ZAFAR007