File size: 3,375 Bytes
5767578
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import SwiftUI

struct DownloadButton: View {
    private var model: Model

    @State private var status: String

    @State private var downloadTask: URLSessionDownloadTask?
    @State private var progress = 0.0
    @State private var observation: NSKeyValueObservation?

    private var onLoad: ((_ model: Model) -> Void)?

    init(model: Model) {
        self.model = model
        status = model.fileExists() ? "downloaded" : "download"
    }

    func onLoad(perform action: @escaping (_ model: Model) -> Void) -> DownloadButton {
        var button = self
        button.onLoad = action
        return button
    }

    private func download() {
        status = "downloading"
        print("Downloading model \(model.name) from \(model.url)")
        guard let url = URL(string: model.url) else { return }

        downloadTask = URLSession.shared.downloadTask(with: url) { temporaryURL, response, error in
            if let error = error {
                print("Error: \(error.localizedDescription)")
                return
            }

            guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
                print("Server error!")
                return
            }

            do {
                if let temporaryURL = temporaryURL {
                    try FileManager.default.copyItem(at: temporaryURL, to: model.fileURL)
                    print("Writing to \(model.filename) completed")
                    status = "downloaded"
                }
            } catch let err {
                print("Error: \(err.localizedDescription)")
            }
        }

        observation = downloadTask?.progress.observe(\.fractionCompleted) { progress, _ in
            self.progress = progress.fractionCompleted
        }

        downloadTask?.resume()
    }

    var body: some View {
        VStack {
            Button(action: {
                if (status == "download") {
                    download()
                } else if (status == "downloading") {
                    downloadTask?.cancel()
                    status = "download"
                } else if (status == "downloaded") {
                    if !model.fileExists() {
                        download()
                    }
                    onLoad?(model)
                }
            }) {
                let title = "\(model.name) \(model.info)"
                if (status == "download") {
                    Text("Download \(title)")
                } else if (status == "downloading") {
                    Text("\(title) (Downloading \(Int(progress * 100))%)")
                } else if (status == "downloaded") {
                    Text("Load \(title)")
                } else {
                    Text("Unknown status")
                }
            }.swipeActions {
                if (status == "downloaded") {
                    Button("Delete") {
                        do {
                            try FileManager.default.removeItem(at: model.fileURL)
                        } catch {
                            print("Error deleting file: \(error)")
                        }
                        status = "download"
                    }
                    .tint(.red)
                }
            }
        }
        .onDisappear() {
            downloadTask?.cancel()
        }
    }
}