【问题标题】:Downloading audio files下载音频文件
【发布时间】:2019-02-24 17:08:39
【问题描述】:

我有一个带有多个控制器的音频应用程序,VCMain 控制器,其中所有书籍和 VCBook 控制器显示关于书籍,其中具有下载音频文件的功能(书籍可以有很多文件)。

点击下载按钮时会出现一个圆形进度条。

如何做到这一点,当我返回 VCMain 并返回已下载的图书时,我拥有进度条设置所需的所有数据(哪些图书仍在下载或正在下载)。我可以同时下载几本书

var progressIndicatorView:CircularProgressView!
lazy var sizeBytes:Int64 = 0
lazy var dowloandedSizeBytes:Int64 = 0


@objc func progressBar(){
    DispatchQueue.main.async {
        self.progressIndicatorView = CircularProgressView(frame: CGRect(x: 5, y: -20, width: 50, height: 50))
        self.view.addSubview(self.progressIndicatorView)
        self.download.isEnabled = false
        self.download.isHidden = true

    }

}

@objc func downloadBook(){

    progressBar()

    for i in UrlName{

        Func.getDownloadSize(url: URL(string: i)!, completion: { [weak self] (size, error) in
            self!.sizeBytes += size
        })

        if let audioUrl = URL(string: i) {
            // create your document folder url
            let documentsUrl = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
            // your destination file url
            let destination = documentsUrl.appendingPathComponent(audioUrl.lastPathComponent)
            // check if it exists before downloading it
            if FileManager().fileExists(atPath: destination.path) {
                print("The file already exists at path")
                bookMarkLoad()
                Func.getDownloadSize(url: URL(string: i)!, completion: { [weak self] (size, error) in
                    self!.dowloandedSizeBytes += size
                })
            } else {
                //  if the file doesn't exist
                //  just download the data from your url
                var url = URLRequest(url: audioUrl)
                url.timeoutInterval = Double.infinity
                let config = URLSessionConfiguration.background(withIdentifier: i)
                let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
                let task = session.downloadTask(with: url)
                task.taskDescription = String(format:"%@" , i )
                task.resume()
                registerBackgroundTask()
              //  let _ = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(backgraundState), userInfo: nil, repeats: true)
            }
        }
    }
}


func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
    if UrlName.contains(downloadTask.taskDescription!){
        if totalBytesExpectedToWrite > 0 {
            dowloandedSizeBytes += bytesWritten
            let progress = Float(dowloandedSizeBytes) / Float(sizeBytes)
            //  print("Progress \(downloadTask) \(progress)")
            DispatchQueue.main.async {
                if self.progressIndicatorView != nil {
                    self.progressIndicatorView.progress = CGFloat(progress)
                }
            }
        }

    }

}

【问题讨论】:

    标签: swift download progress-bar nsurlsessiondownloadtask urlsession


    【解决方案1】:

    这是一个相当广泛的问题,但我建议首先将与下载相关的所有逻辑移至单独的服务。将此类逻辑远离您的视图/视图控制器被认为是一种很好的做法。

    此服务将负责处理下载,并可以通知应用程序的其他部分(例如视图控制器)进度,例如通过使用通知。

    然后 MainVC 可以从服务请求状态信息并更新视图,例如在 viewWillAppear(_:) 方法中。

    有关如何开始构建应用程序和服务的一些示例可以在以下位置找到:

    【讨论】:

    • 这不是 StackOverflow 的真正意义,而且,这是您应该解决的更广泛的问题,而不仅仅是针对此特定问题的一些代码。我添加了一些可以帮助您入门的文章。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多