@@ -28,7 +28,7 @@ import Foundation
28
28
///
29
29
public final class UploadManager {
30
30
31
- private var uploadersByURL : [ URL : ChunkedFileUploader ] = [ : ]
31
+ private var uploadersByID : [ String : ChunkedFileUploader ] = [ : ]
32
32
private var uploadsUpdateDelegatesByToken : [ ObjectIdentifier : any UploadsUpdatedDelegate ] = [ : ]
33
33
private let uploadActor = UploadCacheActor ( )
34
34
private lazy var uploaderDelegate : FileUploaderDelegate = FileUploaderDelegate ( manager: self )
@@ -37,7 +37,12 @@ public final class UploadManager {
37
37
/// to track and control its state
38
38
/// Returns nil if there was no uplod in progress for thr given file
39
39
public func findStartedUpload( ofFile url: URL ) -> MuxUpload ? {
40
- if let uploader = uploadersByURL [ url] {
40
+ if let uploader = Dictionary < URL , ChunkedFileUploader > (
41
+ uniqueKeysWithValues: uploadersByID. mapValues { value in
42
+ ( value. uploadInfo. videoFile, value)
43
+ }
44
+ . values
45
+ ) [ url] {
41
46
return MuxUpload ( wrapping: uploader, uploadManager: self )
42
47
} else {
43
48
return nil
@@ -48,7 +53,7 @@ public final class UploadManager {
48
53
/// Uploads are managed while in-progress or compelted.
49
54
/// Uploads become un-managed when canceled, or if the process dies after they complete
50
55
public func allManagedUploads( ) -> [ MuxUpload ] {
51
- return uploadersByURL . compactMap { ( key, value) in MuxUpload ( wrapping: value, uploadManager: self ) }
56
+ return uploadersByID . compactMap { ( key, value) in MuxUpload ( wrapping: value, uploadManager: self ) }
52
57
}
53
58
54
59
/// Attempts to resume an upload that was previously paused or interrupted by process death
@@ -94,23 +99,28 @@ public final class UploadManager {
94
99
uploadsUpdateDelegatesByToken. removeValue ( forKey: ObjectIdentifier ( delegate) )
95
100
}
96
101
97
- internal func acknowledgeUpload( ofFile url : URL ) {
98
- if let uploader = uploadersByURL [ url ] {
102
+ internal func acknowledgeUpload( id : String ) {
103
+ if let uploader = uploadersByID [ id ] {
99
104
uploader. cancel ( )
100
105
}
101
- uploadersByURL . removeValue ( forKey: url )
106
+ uploadersByID . removeValue ( forKey: id )
102
107
Task . detached {
103
- await self . uploadActor. remove ( uploadAt : url )
108
+ await self . uploadActor. remove ( uploadID : id )
104
109
self . notifyDelegates ( )
105
110
}
106
111
}
107
112
108
113
internal func findUploaderFor( videoFile url: URL ) -> ChunkedFileUploader ? {
109
- return uploadersByURL [ url]
114
+ return Dictionary < URL , ChunkedFileUploader > (
115
+ uniqueKeysWithValues: uploadersByID. mapValues { value in
116
+ ( value. uploadInfo. videoFile, value)
117
+ }
118
+ . values
119
+ ) [ url]
110
120
}
111
121
112
122
internal func registerUploader( _ fileWorker: ChunkedFileUploader , withId id: String ) {
113
- uploadersByURL . updateValue ( fileWorker, forKey: fileWorker. uploadInfo. videoFile )
123
+ uploadersByID . updateValue ( fileWorker, forKey: fileWorker. uploadInfo. id )
114
124
fileWorker. addDelegate ( withToken: UUID ( ) . uuidString, uploaderDelegate)
115
125
Task . detached {
116
126
await self . uploadActor. updateUpload (
@@ -134,7 +144,7 @@ public final class UploadManager {
134
144
135
145
/// The shared instance of this object that should be used
136
146
public static let shared = UploadManager ( )
137
- private init ( ) { }
147
+ internal init ( ) { }
138
148
139
149
private struct FileUploaderDelegate : ChunkedFileUploaderDelegate {
140
150
let manager : UploadManager
@@ -145,7 +155,7 @@ public final class UploadManager {
145
155
manager. notifyDelegates ( )
146
156
}
147
157
switch state {
148
- case . success( _) , . canceled: manager. acknowledgeUpload ( ofFile : uploader. uploadInfo. videoFile )
158
+ case . success( _) , . canceled: manager. acknowledgeUpload ( id : uploader. uploadInfo. id )
149
159
default : do { }
150
160
}
151
161
}
@@ -169,16 +179,31 @@ internal actor UploadCacheActor {
169
179
}
170
180
}
171
181
172
- func getUpload( ofFileAt url : URL ) async -> ChunkedFileUploader ? {
182
+ func getUpload( uploadID : String ) async -> ChunkedFileUploader ? {
173
183
// reminder: doesn't start the uploader, just makes it
174
184
return await Task < ChunkedFileUploader ? , Never > {
175
- let optEntry = try ? persistence. readEntry ( forFileAt : url )
185
+ let optEntry = try ? persistence. readEntry ( uploadID : uploadID )
176
186
guard let entry = optEntry else {
177
187
return nil
178
188
}
179
189
return ChunkedFileUploader ( uploadInfo: entry. uploadInfo, startingAtByte: entry. lastSuccessfulByte)
180
190
} . value
181
191
}
192
+
193
+ func getUpload( ofFileAt: URL ) async -> ChunkedFileUploader ? {
194
+ return await Task < ChunkedFileUploader ? , Never > {
195
+ guard let matchingEntry = try ? persistence. readAll ( ) . filter ( {
196
+ $0. uploadInfo. uploadURL == ofFileAt
197
+ } ) . first else {
198
+ return nil
199
+ }
200
+
201
+ return ChunkedFileUploader (
202
+ uploadInfo: matchingEntry. uploadInfo,
203
+ startingAtByte: matchingEntry. lastSuccessfulByte
204
+ )
205
+ } . value
206
+ }
182
207
183
208
func getAllUploads( ) async -> [ ChunkedFileUploader ] {
184
209
return await Task < [ ChunkedFileUploader ] ? , Never > {
@@ -188,9 +213,9 @@ internal actor UploadCacheActor {
188
213
} . value ?? [ ]
189
214
}
190
215
191
- func remove( uploadAt url : URL ) async {
216
+ func remove( uploadID : String ) async {
192
217
await Task < ( ) , Never > {
193
- try ? persistence. remove ( entryAtAbsUrl : url )
218
+ try ? persistence. remove ( entryAtID : uploadID )
194
219
} . value
195
220
}
196
221
0 commit comments