OLD | NEW |
1 // | 1 // |
2 // FavIcon | 2 // FavIcon |
3 // Copyright © 2016 Leon Breedt | 3 // Copyright © 2016 Leon Breedt |
4 // | 4 // |
5 // Licensed under the Apache License, Version 2.0 (the "License"); | 5 // Licensed under the Apache License, Version 2.0 (the "License"); |
6 // you may not use this file except in compliance with the License. | 6 // you may not use this file except in compliance with the License. |
7 // You may obtain a copy of the License at | 7 // You may obtain a copy of the License at |
8 // | 8 // |
9 // http://www.apache.org/licenses/LICENSE-2.0 | 9 // http://www.apache.org/licenses/LICENSE-2.0 |
10 // | 10 // |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 /// An unexpected HTTP error response was returned. | 54 /// An unexpected HTTP error response was returned. |
55 /// - parameter response: The `HTTPURLResponse` that can be consulted for fu
rther information. | 55 /// - parameter response: The `HTTPURLResponse` that can be consulted for fu
rther information. |
56 case httpError(response: HTTPURLResponse) | 56 case httpError(response: HTTPURLResponse) |
57 } | 57 } |
58 | 58 |
59 /// Base class for performing URL requests in the context of an `NSOperation`. | 59 /// Base class for performing URL requests in the context of an `NSOperation`. |
60 class URLRequestOperation: Operation { | 60 class URLRequestOperation: Operation { |
61 @objc var urlRequest: URLRequest | 61 @objc var urlRequest: URLRequest |
62 var result: URLResult? | 62 var result: URLResult? |
63 | 63 |
64 fileprivate var task: URLSessionDataTask? | 64 private var task: URLSessionDataTask? |
65 fileprivate let session: URLSession | 65 private let session: URLSession |
66 fileprivate var semaphore: DispatchSemaphore? | 66 private var semaphore: DispatchSemaphore? |
67 | 67 |
68 @objc init(url: URL, session: URLSession) { | 68 @objc |
| 69 init(url: URL, session: URLSession) { |
69 self.session = session | 70 self.session = session |
70 self.urlRequest = URLRequest(url: url) | 71 self.urlRequest = URLRequest(url: url) |
71 self.semaphore = nil | 72 self.semaphore = nil |
72 } | 73 } |
73 | 74 |
74 override func main() { | 75 override func main() { |
75 semaphore = DispatchSemaphore(value: 0) | 76 semaphore = DispatchSemaphore(value: 0) |
76 prepareRequest() | 77 prepareRequest() |
77 task = session.dataTask(with: urlRequest, completionHandler: dataTaskCom
pletion) | 78 task = session.dataTask(with: urlRequest, completionHandler: dataTaskCom
pletion) |
78 task?.resume() | 79 task?.resume() |
79 semaphore?.wait() | 80 semaphore?.wait() |
80 } | 81 } |
81 | 82 |
82 override func cancel() { | 83 override func cancel() { |
83 task?.cancel() | 84 task?.cancel() |
84 if let semaphore = semaphore { | 85 if let semaphore = semaphore { |
85 semaphore.signal() | 86 semaphore.signal() |
86 } | 87 } |
87 } | 88 } |
88 | 89 |
89 @objc func prepareRequest() { | 90 @objc |
| 91 func prepareRequest() { |
90 } | 92 } |
91 | 93 |
92 func processResult(_ data: Data?, response: HTTPURLResponse, completion: @es
caping (URLResult) -> Void) { | 94 func processResult(_ data: Data?, response: HTTPURLResponse, completion: @es
caping (URLResult) -> Void) { |
93 fatalError("must override processResult()") | 95 fatalError("must override processResult()") |
94 } | 96 } |
95 | 97 |
96 fileprivate func dataTaskCompletion(_ data: Data?, response: URLResponse?, e
rror: Error?) { | 98 private func dataTaskCompletion(_ data: Data?, response: URLResponse?, error
: Error?) { |
97 guard error == nil else { | 99 guard error == nil else { |
98 result = .failed(error: error!) | 100 result = .failed(error: error!) |
99 self.notifyFinished() | 101 self.notifyFinished() |
100 return | 102 return |
101 } | 103 } |
102 | 104 |
103 guard let response = response as? HTTPURLResponse else { | 105 guard let response = response as? HTTPURLResponse else { |
104 result = .failed(error: URLRequestError.missingResponse) | 106 result = .failed(error: URLRequestError.missingResponse) |
105 self.notifyFinished() | 107 self.notifyFinished() |
106 return | 108 return |
(...skipping 12 matching lines...) Expand all Loading... |
119 } | 121 } |
120 | 122 |
121 processResult(data, response: response) { result in | 123 processResult(data, response: response) { result in |
122 // This block may run on another thread long after dataTaskCompletio
n() finishes! So | 124 // This block may run on another thread long after dataTaskCompletio
n() finishes! So |
123 // wait until then to signal semaphore if we get past checks above. | 125 // wait until then to signal semaphore if we get past checks above. |
124 self.result = result | 126 self.result = result |
125 self.notifyFinished() | 127 self.notifyFinished() |
126 } | 128 } |
127 } | 129 } |
128 | 130 |
129 fileprivate func notifyFinished() { | 131 private func notifyFinished() { |
130 if let semaphore = self.semaphore { | 132 if let semaphore = self.semaphore { |
131 semaphore.signal() | 133 semaphore.signal() |
132 } | 134 } |
133 } | 135 } |
134 } | 136 } |
135 | 137 |
136 typealias URLRequestWithCallback = (request: URLRequestOperation, completion: (U
RLResult) -> Void) | 138 typealias URLRequestWithCallback = (request: URLRequestOperation, completion: (U
RLResult) -> Void) |
137 | 139 |
138 func executeURLOperations(_ operations: [URLRequestOperation], | 140 func executeURLOperations(_ operations: [URLRequestOperation], |
139 concurrency: Int = 2, | 141 concurrency: Int = 2, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 } | 187 } |
186 queue.addOperation(overallCompletion) | 188 queue.addOperation(overallCompletion) |
187 | 189 |
188 queue.isSuspended = false | 190 queue.isSuspended = false |
189 } | 191 } |
190 | 192 |
191 func urlRequestOperation(_ operation: URLRequestOperation, | 193 func urlRequestOperation(_ operation: URLRequestOperation, |
192 completion: @escaping (URLResult) -> Void) -> URLReques
tWithCallback { | 194 completion: @escaping (URLResult) -> Void) -> URLReques
tWithCallback { |
193 return (request: operation, completion: completion) | 195 return (request: operation, completion: completion) |
194 } | 196 } |
OLD | NEW |