【Swift】動画DLの進捗をプログレスバーで表示する

## 概要
ネットから動画をDLして進捗をプログレスバーで見れるようにするサンプルです。
<img src="https://storage.googleapis.com/zenn-user-upload/6ddf0eef5f20-20230604.png" width="240" />

### プログレスバー追加
まず初めに進捗を表示するプログレスバーを画面に追加します。

```swift:ViewController.swift
import UIKit

class ViewController: UIViewController {
    var progressView: UIProgressView!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        progressView = UIProgressView(progressViewStyle: .default)
        progressView.center = view.center
        progressView.progress = .zero
        view.addSubview(progressView)
    }
}
```

### DL関数
次にDLを開始する関数を実装します。
DLには以下のURLを使いました。

https://www.home-movie.biz/mov/hts-samp001.mp4

```swift:ViewController.swift
private func startDownload() {
    let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
    let downloadTask = session.downloadTask(with: videoURL)
    downloadTask.resume()
}
```

### DL完了検知
次にDL完了時に画面を更新します。
`urlSession(_:downloadTask:didFinishDownloadingTo:)`を使って検知できます。

https://developer.apple.com/documentation/foundation/urlsessiondownloaddelegate/1411575-urlsession

DLが完了したらプログレスバーの進捗を100%にします。

```swift
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
    DispatchQueue.main.async {
        self.progressView.progress = 1.0
    }
}
```

### DL進捗検知
DLの進捗をリアルタイムに取得して画面に反映していきます。

`urlSession(_:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:)`を使ってDLの進捗を検知できます。

https://developer.apple.com/documentation/foundation/urlsessiondownloaddelegate/1409408-urlsession

```swift
func urlSession(
    _ session: URLSession,
    downloadTask: URLSessionDownloadTask,
    didWriteData bytesWritten: Int64,
    totalBytesWritten: Int64,
    totalBytesExpectedToWrite: Int64
) {
    let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)

    DispatchQueue.main.async {
        self.progressView.progress = progress
    }
}
```

全体のコードはこちらです。

```swift:ViewController.swift
import UIKit

class ViewController: UIViewController, URLSessionDownloadDelegate {
    var progressView: UIProgressView!
    
    private let videoURL = URL(string: "https://www.home-movie.biz/mov/hts-samp001.mp4")!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        progressView = UIProgressView(progressViewStyle: .default)
        progressView.center = view.center
        progressView.progress = .zero
        view.addSubview(progressView)
        
        startDownload()
    }
    
    private func startDownload() {
        let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
        let downloadTask = session.downloadTask(with: videoURL)
        downloadTask.resume()
    }
    
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        DispatchQueue.main.async {
            self.progressView.progress = 1.0
        }
    }
    
    func urlSession(
        _ session: URLSession,
        downloadTask: URLSessionDownloadTask,
        didWriteData bytesWritten: Int64,
        totalBytesWritten: Int64,
        totalBytesExpectedToWrite: Int64
    ) {
        let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
        
        DispatchQueue.main.async {
            self.progressView.progress = progress
        }
    }
}
```