@@ -11,6 +11,39 @@ import os.log
1111
1212private let Shared = UploadService ( )
1313
14+ // Provides synchronized access to task data and completion handlers.
15+ struct TaskState {
16+ typealias CompletionHandler = ( Data ? , URLResponse ? , Swift . Error ? ) -> Void
17+
18+ private var taskData : [ URLSessionDataTask : Data ] = [ : ]
19+ private var taskCompletion : [ URLSessionDataTask : CompletionHandler ] = [ : ]
20+ private let syncQueue = DispatchQueue ( label: " io.filestack.TaskState-sync-queue " )
21+
22+ func getData( for task: URLSessionDataTask ) -> Data ? {
23+ syncQueue. sync { taskData [ task] }
24+ }
25+
26+ mutating func setData( for task: URLSessionDataTask , data: Data ) {
27+ syncQueue. sync { taskData [ task] = data }
28+ }
29+
30+ func getCompletion( for task: URLSessionDataTask ) -> CompletionHandler ? {
31+ syncQueue. sync { taskCompletion [ task] }
32+ }
33+
34+ mutating func setCompletionHandler( for task: URLSessionDataTask , completionHandler: @escaping CompletionHandler ) {
35+ syncQueue. sync { taskCompletion [ task] = completionHandler }
36+ }
37+
38+ mutating func forget( task: URLSessionDataTask ) {
39+ syncQueue. sync {
40+ taskData. removeValue ( forKey: task)
41+ taskCompletion. removeValue ( forKey: task)
42+ }
43+ }
44+ }
45+
46+
1447/// Service used for uploading files.
1548@objc ( FSUploadService)
1649public final class UploadService : NSObject , NetworkingService {
@@ -20,8 +53,7 @@ public final class UploadService: NSObject, NetworkingService {
2053
2154 // MARK: - Private Properties
2255
23- private var taskData : [ URLSessionDataTask : Data ] = [ : ]
24- private var taskCompletion : [ URLSessionDataTask : ( Data ? , URLResponse ? , Swift . Error ? ) -> Void ] = [ : ]
56+ private var taskState = TaskState ( )
2557
2658 // MARK: - Public Properties
2759
@@ -52,10 +84,9 @@ extension UploadService: URLSessionDataDelegate {
5284 completionHandler ( URLSession . ResponseDisposition . allow)
5385
5486 if response. expectedContentLength == 0 || dataTask. error != nil {
55- let completionHandler = taskCompletion [ dataTask]
87+ let completionHandler = taskState . getCompletion ( for : dataTask)
5688
57- taskData. removeValue ( forKey: dataTask)
58- taskCompletion. removeValue ( forKey: dataTask)
89+ taskState. forget ( task: dataTask)
5990
6091 DispatchQueue . main. async {
6192 completionHandler ? ( nil , response, dataTask. error)
@@ -64,19 +95,18 @@ extension UploadService: URLSessionDataDelegate {
6495 }
6596
6697 public func urlSession( _ session: URLSession , dataTask: URLSessionDataTask , didReceive data: Data ) {
67- if var existingData = taskData [ dataTask] {
98+ if var existingData = taskState . getData ( for : dataTask) {
6899 existingData. append ( data)
69- taskData [ dataTask] = existingData
100+ taskState . setData ( for : dataTask, data : existingData)
70101 } else {
71- taskData [ dataTask] = data
102+ taskState . setData ( for : dataTask, data : data)
72103 }
73104
74105 if let response = dataTask. response {
75- let data = taskData [ dataTask]
76- let completionHandler = taskCompletion [ dataTask]
106+ let data = taskState . getData ( for : dataTask)
107+ let completionHandler = taskState . getCompletion ( for : dataTask)
77108
78- taskData. removeValue ( forKey: dataTask)
79- taskCompletion. removeValue ( forKey: dataTask)
109+ taskState. forget ( task: dataTask)
80110
81111 DispatchQueue . main. async {
82112 completionHandler ? ( data, response, dataTask. error)
@@ -107,12 +137,16 @@ extension UploadService {
107137 defer { try ? FileManager . default. removeItem ( at: dataURL) }
108138
109139 task = session. uploadTask ( with: request, fromFile: dataURL)
140+
141+ taskState. setCompletionHandler ( for: task, completionHandler: completionHandler)
110142 } else {
111- task = session. uploadTask ( with: request, from: data)
143+ task = session. uploadTask ( with: request, from: data) { ( data, response, error) in
144+ DispatchQueue . main. async {
145+ completionHandler ( data, response, error)
146+ }
147+ }
112148 }
113149
114- taskCompletion [ task] = completionHandler
115-
116150 if let uploadProgress = uploadProgress {
117151 var progressObservers : [ NSKeyValueObservation ] = [ ]
118152
0 commit comments