|
1 | 1 | class SessionDelegate: NSObject { |
| 2 | + class SessionDelegateTask { |
| 3 | + let completionHandler: (Data?, URLResponse?, Error?) -> Void |
| 4 | + let progressHandler: ((Progress) -> Void)? |
| 5 | + var data = Data() |
| 6 | + |
| 7 | + init(completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void, progressHandler: ((Progress) -> Void)? = nil) { |
| 8 | + self.completionHandler = completionHandler |
| 9 | + self.progressHandler = progressHandler |
| 10 | + } |
| 11 | + |
| 12 | + func didReceiveData(data: Data) { |
| 13 | + self.data.append(data) |
| 14 | + } |
| 15 | + } |
2 | 16 |
|
3 | | - private var tasks: [Int: (Progress) -> Void] = [:] |
4 | | - private let lock = NSLock() |
| 17 | + private var tasks: [Int: SessionDelegateTask] = [:] |
| 18 | + private let lock = Mutex() |
5 | 19 |
|
6 | | - func add(task: URLSessionTask, progressHandler: @escaping (Progress) -> Void) { |
7 | | - lock.lock() |
8 | | - defer { lock.unlock() } |
| 20 | + func add(task: URLSessionTask, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void, progressHandler: ((Progress) -> Void)? = nil) { |
| 21 | + self.lock.lock() |
| 22 | + defer { self.lock.unlock() } |
9 | 23 |
|
10 | | - self.tasks[task.taskIdentifier] = progressHandler |
| 24 | + self.tasks[task.taskIdentifier] = SessionDelegateTask(completionHandler: completionHandler, progressHandler: progressHandler) |
11 | 25 | } |
12 | 26 |
|
13 | | - func get(task: URLSessionTask) -> ((Progress) -> Void)? { |
14 | | - lock.lock() |
15 | | - defer { lock.unlock() } |
16 | | - |
17 | | - return self.tasks[task.taskIdentifier] |
| 27 | + func get(task: URLSessionTask) -> SessionDelegateTask? { |
| 28 | + return lock.withLock { |
| 29 | + return self.tasks[task.taskIdentifier] |
| 30 | + } |
18 | 31 | } |
19 | 32 |
|
20 | 33 | func remove(task: URLSessionTask) { |
21 | | - lock.lock() |
22 | | - defer { lock.unlock() } |
| 34 | + self.lock.lock() |
| 35 | + defer { self.lock.unlock() } |
23 | 36 |
|
24 | 37 | self.tasks.removeValue(forKey: task.taskIdentifier) |
25 | 38 | } |
26 | 39 | } |
27 | 40 |
|
| 41 | +extension SessionDelegate: URLSessionDataDelegate { |
| 42 | + func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Swift.Void) { |
| 43 | + completionHandler(URLSession.ResponseDisposition.allow) |
| 44 | + } |
| 45 | +} |
| 46 | + |
28 | 47 | extension SessionDelegate: URLSessionTaskDelegate { |
29 | 48 | func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) { |
30 | | - if let progressHandler = self.get(task: task) { |
| 49 | + if let sessionTask = self.get(task: task), let progressHandler = sessionTask.progressHandler { |
31 | 50 | progressHandler(Progress((totalBytesSent/totalBytesExpectedToSend)) * 100) |
32 | 51 | } |
33 | 52 | } |
34 | 53 |
|
| 54 | + func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { |
| 55 | + if let sessionTask = self.get(task: dataTask) { |
| 56 | + sessionTask.didReceiveData(data: data) |
| 57 | + } |
| 58 | + } |
| 59 | + |
35 | 60 | func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { |
36 | | - self.remove(task: task) |
| 61 | + if let sessionTask = self.get(task: task) { |
| 62 | + self.remove(task: task) |
| 63 | + |
| 64 | + sessionTask.completionHandler(sessionTask.data, task.response, error) |
| 65 | + } |
37 | 66 | } |
38 | 67 | } |
0 commit comments