| 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 | 
|---|