首页 > 解决方案 > Xcode Swift URLSession 从 URL 下载视频

问题描述

我正在构建一个用于从 url 下载视频的应用程序,但我的问题是当我启动我的应用程序以首次运行它时,它工作得很好,但是当我尝试启动另一个视图控制器并回来时它不再下载,这是我的代码:-

var downloadTask: URLSessionDownloadTask!
var backgroundSession: URLSession!


override func viewDidLoad() {
    super.viewDidLoad()



    self.basheOneProgress.setProgress(0, animated: false)


    sessionConfiguration()
}

// Session Configuration.....
func sessionConfiguration() {
    let backgroundSessionConfiguration = URLSessionConfiguration.background(withIdentifier: "backgroundSession")
    backgroundSession = Foundation.URLSession(configuration: backgroundSessionConfiguration, delegate: self, delegateQueue: OperationQueue.main)
}

// Download Bashe ONE Video.
@IBAction func downloadBasheOne(_ sender: Any) {
    let basheOneURL = URL(string: "http://pertuk.com/bashe1.mp4")
    downloadTask = backgroundSession.downloadTask(with: basheOneURL!)
    if downloadTask != nil {
        let alertController = UIAlertController(title: "Download", message: "Do you wanna download?", preferredStyle: .alert)
        let yesButton = UIAlertAction(title: "Yes", style: .default) { (alertController: UIAlertAction) in
            self.downloadTask.resume()
        }
        let cancelButton = UIAlertAction(title: "No", style: .cancel, handler: nil)
        alertController.addAction(yesButton)
        alertController.addAction(cancelButton)
        self.present(alertController, animated: true, completion: nil)
    } else {
        let alertController = UIAlertController(title: "Download", message: "Resuming Download", preferredStyle: .alert)
        let yesButton = UIAlertAction(title: "Yes", style: .default) { (alertAction: UIAlertAction) in
            self.downloadTask.resume()
        }
        alertController.addAction(yesButton)
        self.present(alertController, animated: true, completion: nil)
    }
}
@IBAction func cancelBasheOne(_ sender: UIButton) {
    if downloadTask == nil {
        let alertController = UIAlertController(title: "0%", message: "", preferredStyle: .alert)
        let action = UIAlertAction(title: "OK", style: .default, handler: nil)
        alertController.addAction(action)
        self.present(alertController, animated: true, completion: nil)
    } else {
        let alertController = UIAlertController(title: "Cancel", message: "Cancel This Download", preferredStyle: .alert)
        let yesButton = UIAlertAction(title: "Yes", style: .default) { (action: UIAlertAction) in
            self.downloadTask.cancel()
        }
        alertController.addAction(yesButton)
        self.present(alertController, animated: true, completion: nil)
    }
}
@IBOutlet var basheOneProgress: UIProgressView!

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {

    let url = downloadTask.response?.url?.lastPathComponent
    if (url?.hasSuffix(".mp4"))! {
        guard let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }

        if !FileManager.default.fileExists(atPath: documentsDirectoryURL.appendingPathComponent((downloadTask.response?.url?.lastPathComponent)!).path) {



            let destinationURL = documentsDirectoryURL.appendingPathComponent(downloadTask.response?.suggestedFilename ?? ((downloadTask.response?.url)?.lastPathComponent)!)

            do {
                try? FileManager.default.removeItem(at: destinationURL)
                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 {
                                DispatchQueue.main.async {
                                    print("Video saved") // successfully saved video in your gallery
                                }

                            } else {
                                print(error as Any)
                            }
                        }
                    }
                })

            } catch {print(error)}
        } else {
            let destinationURL = documentsDirectoryURL.appendingPathComponent(downloadTask.response?.suggestedFilename ?? ((downloadTask.response?.url)?.lastPathComponent)!)

            do {
                try FileManager.default.removeItem(at: destinationURL)
                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 {
                                DispatchQueue.main.async {
                                    print("Video saved") // successfully saved video in your gallery
                                }

                            } else {
                                print(error as Any)
                            }
                        }
                    }
                })
            } catch {print(error)}

        }
    } else {

    }
}



func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {

    if totalBytesExpectedToWrite > 0 {
        basheOneProgress.setProgress(Float(totalBytesWritten)/Float(totalBytesExpectedToWrite), animated: true)
    } else if totalBytesExpectedToWrite == 0 {
        basheOneProgress.setProgress(0.0, animated: false)
    } else if totalBytesWritten == 100 {
        basheOneProgress.setProgress(100, animated: false)
    }
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {

    downloadTask = nil

    basheOneProgress.setProgress(0, animated: false)

    if (error != nil) {
        print(error!.localizedDescription)
    } else {
        print("The Data Finished Transfering")
    }

}

}

这是我回到下载视频的 ViewController 时的错误代码:-

(带有标识符 backgroundSession 的背景 URLSession 已经存在!)

标签: iosswiftxcodeurlxcode10

解决方案


推荐阅读