SwiftUIで動画や画像をダウンロードする方法を説明する。
結論
ダウンローダーのモデルとなるclass(中身はある程度決まった型のコード)を定義し、ContentViewで使う。
具体例
入力したURLの動画や画像をダウンロードしプレビュー表示するAppを例に説明する。
ダウンローダーのモデルとなるclass ダウンローダーのモデル を定義する
import SwiftUI
class ダウンローダーのモデル: NSObject,
ObservableObject,
URLSessionDownloadDelegate,
UIDocumentInteractionControllerDelegate {
@Published var ダウンロードと保存をするタスク: URLSessionDownloadTask!
@Published var ダウンロード進捗率: Int = 0
// ■ 1 ダウンロード開始
func ダウンロード開始(アドレス: String) {
guard let 有効アドレス = URL(string: アドレス) else {
print("URLが無効")
return
}
ダウンロード進捗率 = 0
let セッション = URLSession(configuration: .default,
delegate: self,
delegateQueue: nil)
ダウンロードと保存をするタスク = セッション.downloadTask(with: 有効アドレス)
ダウンロードと保存をするタスク.resume() // ダウンロード開始
print("ダウンロード開始")
}
// ■ 2 ダウンロード中(ダウンロード中は自動的に実行)
func urlSession(_ session: URLSession,
downloadTask: URLSessionDownloadTask,
didWriteData bytesWritten: Int64,
totalBytesWritten: Int64,
totalBytesExpectedToWrite: Int64) {
let ダウンロードできたサイズ = Float(totalBytesWritten)
let トータルサイズ = Float(totalBytesExpectedToWrite)
let 進捗率 = Int(round(ダウンロードできたサイズ / トータルサイズ * 100))
// URLセッションはバックグラウンドスレッドで実行されるので
// UIのアップデートに関する処理はメインスレッドで実行
DispatchQueue.main.async {
self.ダウンロード進捗率 = 進捗率
}
}
// ■ 3 ダウンロード完了(ダウンロード完了時に自動的に実行)
func urlSession(_ session: URLSession,
downloadTask: URLSessionDownloadTask,
didFinishDownloadingTo location: URL) {
print("ダウンロード完了")
guard let リクエストのURL = downloadTask.originalRequest?.url else {
print("リクエストのURLエラー")
return
}
let ファイル名 = リクエストのURL.lastPathComponent
let 一時ファイルパス = location
let 最終パス = FileManager.default.urls(for: .documentDirectory,
in: .userDomainMask)[0]
let 最終ファイルパス = 最終パス.appendingPathComponent(ファイル名)
print(最終ファイルパス)
try? FileManager.default.removeItem(at: 最終ファイルパス)
do {
try FileManager.default.copyItem(at: 一時ファイルパス, to: 最終ファイルパス)
print("ファイル保存完了")
DispatchQueue.main.async {
// ■ 3 -> 4 ダウンロードしたファイルをプレビュー表示
print("プレビューします")
let controller = UIDocumentInteractionController(url: 最終ファイルパス)
controller.delegate = self
controller.presentPreview(animated: true)
}
} catch {
print("ファイルコピーでエラー")
}
}
// ■ 4 プレビュー(ダウンロードしたファイルをプレビュー)
func documentInteractionControllerViewControllerForPreview(
_ controller: UIDocumentInteractionController) -> UIViewController {
let scenes = UIApplication.shared.connectedScenes
let windowScenes = scenes.first as? UIWindowScene
let window = windowScenes?.windows.first
return window!.rootViewController!
}
// ■ 5 エラー出力(ダウンロード完了時に自動的に実行)
func urlSession(_ session: URLSession,
task: URLSessionTask,
didCompleteWithError error: Error?) {
if let error = error {
print("エラー有り")
print(error)
return
} else {
print("エラー無し")
}
}
}
ContentViewでこのclassのインスタンスを作成して使う。
import SwiftUI
struct ContentView: View {
@StateObject var ダウンローダー = ダウンローダーのモデル()
@State var url = "http://swiftui.diandian.online/wp-content/uploads/2022/08/rika_movie.mp4"
var body: some View {
VStack {
TextField("URL", text: $url)
.padding()
.background(Color(red: 0.95, green: 0.95, blue: 0.95))
Button("ダウンロード") {
ダウンローダー.ダウンロード開始(アドレス: url)
}
.buttonStyle(.borderedProminent)
.padding()
Text(String(ダウンローダー.ダウンロード進捗率) + "%")
}
.padding()
}
}
完成。以下にAppの動作をGIF動画で示す。
まとめ
SwiftUIで動画や画像をダウンロードする方法を説明した。
コメント