URLSession dataTask долгая задержка

Когда я запрашиваю API из своего кода, я получаю ответ через 4-6 секунд, что слишком долго. От почтальона я получаю ответ через 120 мс. Что-то в моем коде идет не так? вот мой код, я проверяю время между этими двумя отпечатками:

func makeUrlRequest<T: Codable>(_ request: URLRequest, resultHandler: @escaping (Result<T, RequestError>) -> Void) {
        var req = request
        req.addValue("application/json", forHTTPHeaderField: "Content-Type")
        req.addValue("application/json", forHTTPHeaderField: "Accept")
        let config = URLSessionConfiguration.default
        let urlSession = URLSession(configuration: config, delegate: self, delegateQueue: .main)
        print("Request: start at: \(Date())") //Request: start at: 2021-04-09 06:53:32 +0000
        let urlTask = urlSession.dataTask(with: req) { data, response, error in
            print("Request: finished at: \(Date())") //Request: finished at: 2021-04-09 06:53:36 +0000
            DispatchQueue.main.async {
                guard error == nil else {
                    resultHandler(.failure(.clientError))
                    return
                }

                guard let response = response as? HTTPURLResponse, 200...299 ~= response.statusCode else {
                    resultHandler(.failure(.serverError))
                    return
                }

                guard let data = data else {
                    resultHandler(.failure(.noData))
                    return
                }

                guard let decodedData: T = self.decodedData(data) else {
                    resultHandler(.failure(.dataDecodingError))
                    return

                }
                
                resultHandler(.success(decodedData))
            }
        }

        urlTask.resume()
    }

person Gorthez    schedule 09.04.2021    source источник
comment
Вы неправильно создаете URLSession. Это должен быть постоянный, а не локальный экземпляр, и у него не должно быть делегата, потому что вы используете обработчик завершения.   -  person matt    schedule 09.04.2021
comment
@matt Я использую делегат, чтобы обойти проверку сертификата (только сейчас). Что касается инициализации, я переместил инициализацию URLSession в класс init, но все еще есть задержка   -  person Gorthez    schedule 09.04.2021


Ответы (1)


Вместо того

let urlSession = URLSession(configuration: config, delegate: self, delegateQueue: .main)
print("Request: start at: \(Date())") //Request: start at: 2021-04-09 06:53:32 +0000
let urlTask = urlSession.dataTask(with: req) { data, response, error in...

Вы должны использовать

let task = URLSession.shared.dataTask(with: req) { (data, response, error) in...

РЕДАКТИРОВАТЬ:

Я вижу, что вы хотите использовать делегата. В этом случае вам не следует использовать обработчик завершения, а вместо этого добавить методы делегата:

func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)

Дополнительную информацию см. В документации Apple.

person whyp    schedule 09.04.2021
comment
Не хочу критиковать, но это именно то, что я сказал в своем комментарии: создание вами сеанса URL-адреса было неправильным. Либо используйте делегат, либо используйте обработчик завершения; не пытайтесь смешать их вместе. - person matt; 09.04.2021
comment
@matt Полностью согласен. Я чувствовал, что OP нуждается в более подробном ответе и более сильном толчке в правильном направлении. Было бы лучше, если бы я сослался на ваш комментарий в своем ответе. Спасибо за ваши замечательные книги. Программирование на iOS 5 помогло мне начать еще в 2012 году. - person whyp; 10.04.2021
comment
Никакой критики не предполагалось! На самом деле я пытался заставить ОП увидеть, что ответ уже был дан, если кто-то желает слушать. :) Большое спасибо за приятный комментарий. - person matt; 10.04.2021