@@ -28,7 +28,7 @@ import Foundation
2828///
2929public final class UploadManager {
3030
31- private var uploadersByURL : [ URL : ChunkedFileUploader ] = [ : ]
31+ private var uploadersByID : [ String : ChunkedFileUploader ] = [ : ]
3232 private var uploadsUpdateDelegatesByToken : [ ObjectIdentifier : any UploadsUpdatedDelegate ] = [ : ]
3333 private let uploadActor = UploadCacheActor ( )
3434 private lazy var uploaderDelegate : FileUploaderDelegate = FileUploaderDelegate ( manager: self )
@@ -37,7 +37,12 @@ public final class UploadManager {
3737 /// to track and control its state
3838 /// Returns nil if there was no uplod in progress for thr given file
3939 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] {
4146 return MuxUpload ( wrapping: uploader, uploadManager: self )
4247 } else {
4348 return nil
@@ -48,7 +53,7 @@ public final class UploadManager {
4853 /// Uploads are managed while in-progress or compelted.
4954 /// Uploads become un-managed when canceled, or if the process dies after they complete
5055 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 ) }
5257 }
5358
5459 /// Attempts to resume an upload that was previously paused or interrupted by process death
@@ -94,23 +99,28 @@ public final class UploadManager {
9499 uploadsUpdateDelegatesByToken. removeValue ( forKey: ObjectIdentifier ( delegate) )
95100 }
96101
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 ] {
99104 uploader. cancel ( )
100105 }
101- uploadersByURL . removeValue ( forKey: url )
106+ uploadersByID . removeValue ( forKey: id )
102107 Task . detached {
103- await self . uploadActor. remove ( uploadAt : url )
108+ await self . uploadActor. remove ( uploadID : id )
104109 self . notifyDelegates ( )
105110 }
106111 }
107112
108113 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]
110120 }
111121
112122 internal func registerUploader( _ fileWorker: ChunkedFileUploader , withId id: String ) {
113- uploadersByURL . updateValue ( fileWorker, forKey: fileWorker. uploadInfo. videoFile )
123+ uploadersByID . updateValue ( fileWorker, forKey: fileWorker. uploadInfo. id )
114124 fileWorker. addDelegate ( withToken: UUID ( ) . uuidString, uploaderDelegate)
115125 Task . detached {
116126 await self . uploadActor. updateUpload (
@@ -134,7 +144,7 @@ public final class UploadManager {
134144
135145 /// The shared instance of this object that should be used
136146 public static let shared = UploadManager ( )
137- private init ( ) { }
147+ internal init ( ) { }
138148
139149 private struct FileUploaderDelegate : ChunkedFileUploaderDelegate {
140150 let manager : UploadManager
@@ -145,7 +155,7 @@ public final class UploadManager {
145155 manager. notifyDelegates ( )
146156 }
147157 switch state {
148- case . success( _) , . canceled: manager. acknowledgeUpload ( ofFile : uploader. uploadInfo. videoFile )
158+ case . success( _) , . canceled: manager. acknowledgeUpload ( id : uploader. uploadInfo. id )
149159 default : do { }
150160 }
151161 }
@@ -169,16 +179,31 @@ internal actor UploadCacheActor {
169179 }
170180 }
171181
172- func getUpload( ofFileAt url : URL ) async -> ChunkedFileUploader ? {
182+ func getUpload( uploadID : String ) async -> ChunkedFileUploader ? {
173183 // reminder: doesn't start the uploader, just makes it
174184 return await Task < ChunkedFileUploader ? , Never > {
175- let optEntry = try ? persistence. readEntry ( forFileAt : url )
185+ let optEntry = try ? persistence. readEntry ( uploadID : uploadID )
176186 guard let entry = optEntry else {
177187 return nil
178188 }
179189 return ChunkedFileUploader ( uploadInfo: entry. uploadInfo, startingAtByte: entry. lastSuccessfulByte)
180190 } . value
181191 }
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+ }
182207
183208 func getAllUploads( ) async -> [ ChunkedFileUploader ] {
184209 return await Task < [ ChunkedFileUploader ] ? , Never > {
@@ -188,9 +213,9 @@ internal actor UploadCacheActor {
188213 } . value ?? [ ]
189214 }
190215
191- func remove( uploadAt url : URL ) async {
216+ func remove( uploadID : String ) async {
192217 await Task < ( ) , Never > {
193- try ? persistence. remove ( entryAtAbsUrl : url )
218+ try ? persistence. remove ( entryAtID : uploadID )
194219 } . value
195220 }
196221
0 commit comments