     // MARK: - Private funcs
     
     private func callResponseListeners(endpointName: String, result: Result<HTTPURLResponse, APIError>) {
-        self.responseListeners.forEach({ listener in
-            listener.queue.async {
-                listener.callback(endpointName, result)
-            }
-        })
+        DispatchQueue.main.async {
+            for listener in self.responseListeners {
+                listener.queue.async {
+                    listener.callback(endpointName, result)
+                }
+            }
+        }
     }
 }
 

        completesOn completionQueue: DispatchQueue,
        completion: @escaping (Result<ResponseType, APIError>) -> Void
    ) {
        let handleResult: (Result<(ResponseType, HTTPURLResponse), APIError>) -> Void = { [weak self] result in
            switch result {
            case let .success((response, httpResponse)):
                // tell any listeners about the http response
                self?.callResponseListeners(
                    endpointName: request.endpoint,
                    result: .success(httpResponse)
                )
                
                // complete with success!
                completionQueue.async {
                    completion(.success(response))
                }
            case let .failure(error):
                
                // tell any listeners about the error
                self?.callResponseListeners(
                    endpointName: request.endpoint,
                    result: .failure(error)
                )
                
                // complete with failure :(
                completionQueue.async {
                    completion(.failure(error))
                }
            }
        }
        
        var endpointURL = self.baseURL.appendingPathComponent(request.endpoint)
        let headers = self.clientHeaders
        
        // add the request's queryParams to the url

            urlReq.httpBody = try request.body?.encode(self.defaultEncoder)
        } catch {
            // We were unable to make the request
            self.handleRequestResult(.failure(.unencodableRequest(error: error)), endpointName: endpointName, completesOn: completionQueue, completion: completion)
            return
        }
        let reqDecoder = request.decoder
        let defaultDecoder = self.defaultDecoder
        let task = self.urlSession.dataTask(with: urlReq) { [weak self] (data, urlResponse, error) in
            if let data = data, let httpResponse = urlResponse as? HTTPURLResponse {
                if (200..<300).contains(httpResponse.statusCode) {
                    do {
                        let successResponse = try reqDecoder.decode(data, defaultDecoder)
                        // Successfully decoded the expected ResponseType!
                        self?.handleRequestResult(.success((successResponse, httpResponse)), endpointName: endpointName, completesOn: completionQueue, completion: completion)
                        return
                    } catch let decodeError {
                        // Unable to decode the expected ResponseType.
                        self?.handleRequestResult(.failure(.decode(error: decodeError, data: data)), endpointName: endpointName, completesOn: completionQueue, completion: completion)
                        return
                    }
                } else if let errorResponse = try? JSONDecoder().decode(APIError.ServerResponse.self, from: data) {
                    // We got a specific error object in the server's response.
                    self?.handleRequestResult(.failure(.server(errorResponse, httpResponse: httpResponse)), endpointName: endpointName, completesOn: completionQueue, completion: completion)
                    return
                } else if let stringResponse = String(data: data, encoding: .utf8) {
                    // We got some error data in the server's response, but we cant decode it.
                    self?.handleRequestResult(.failure(.undecodableServer(stringResponse, httpResponse: httpResponse)), endpointName: endpointName, completesOn: completionQueue, completion: completion)
                    return
                }
            }
            
            if let error = error {
                // We got a system networking error.
                self?.handleRequestResult(.failure(.network(error: error, urlResponse: urlResponse)), endpointName: endpointName, completesOn: completionQueue, completion: completion)
                return
            } else {
                // The request failed for some unknown reason.
                self?.handleRequestResult(.failure(.failedRequest(urlResponse: urlResponse)), endpointName: endpointName, completesOn: completionQueue, completion: completion)
                return
            }
        }
        task.resume()
    }
    
    fileprivate func handleRequestResult<ResponseType>(_ result: Result<(ResponseType, HTTPURLResponse), APIError>, endpointName: String, completesOn completionQueue: DispatchQueue, completion: @escaping (Result<ResponseType, APIError>) -> Void) {
        switch result {
        case let .success((response, httpResponse)):
            // tell any listeners about the http response
            self.callResponseListeners(
                endpointName: endpointName,
                result: .success(httpResponse)
            )
            
            // complete with success!
            completionQueue.async {
                completion(.success(response))
            }
        case let .failure(error):
            
            // tell any listeners about the error
            self.callResponseListeners(
                endpointName: endpointName,
                result: .failure(error)
            )
            
            // complete with failure :(
            completionQueue.async {
                completion(.failure(error))
            }
        }
    }
}

