Загрузка MultipartFormData с помощью Alamofire

Я пытался реализовать данные многостраничной формы с помощью Alamofire. Я сделал код, и он отлично работает для запросов, которые выполняются менее 60 секунд. Однако, если запрос требует больше, он завершается, а загрузка не завершается:

Просмотр переменных

Кроме того, я получаю этот вывод (вероятно, это означает, что мое приложение пытается записать в закрытый TCP-сокет):

2017-06-20 17: 22: 21.924948 приложение [4645: 1381848] [] nw_endpoint_flow_prepare_output_frames [110.1 10.39.80.102:8550 готово поток сокета (удовлетворено)] Не удалось использовать 1 кадр, отмечен как сбой

2017-06-20 17: 22: 21.928262 приложение [4645: 1381848] [] nw_endpoint_handler_add_write_request [110.1 10.39.80.102:8550 failed socket-flow (выполнено)] не может принимать запросы на запись

2017-06-20 17: 22: 21.929278 приложение [4645: 1381027] [] __tcp_connection_write_eof_block_invoke Запись получена ошибка обратного вызова закрытия: [22] Неверный аргумент

Я уже пытался изменить URLSessionConfiguration, который я использую для выполнения запроса, изменив параметры timeoutIntervalForRequest и timeoutIntervalForResource:

func initManager(timeoutInterval:Double) {
    
    let configuration = URLSessionConfiguration.default
    
    configuration.timeoutIntervalForRequest = timeoutInterval
    configuration.timeoutIntervalForResource = timeoutInterval
    
    alamofireManager = Alamofire.SessionManager(configuration: configuration)
}

Однако у меня все еще та же проблема. Кто-нибудь знает, как это решить? Или кто-нибудь сталкивается с такой же проблемой?

Спасибо


person Tiago Pereira    schedule 20.06.2017    source источник


Ответы (1)


Возможно, вы достигли ограничения по времени выполнения на стороне сервера. Тем не менее, я думаю, что в iOS 10.0 - 10.2.x также есть ошибка, которая может вызвать такое неправильное поведение. (Подробнее см. https://forums.developer.apple.com/thread/67606. .)

Даже если вы устраните причину этой конкретной проблемы, основная проблема здесь - проблема дизайна, а не проблема с запросом как таковым. Сети ненадежны, а сотовые сети - вдвойне. Шансы на поддержание сотовой связи более минуты примерно такие же, как и на выигрыш в лотерею. (Да, это преувеличение, но идею вы поняли.)

Я бы предложил следующий альтернативный подход:

  • Конечная точка POST или PUT, которая принимает имя файла, поток данных и необязательное смещение для записи байтов.
  • Отдельная конечная точка POST, которая обрабатывает файл, загруженный с помощью вышеупомянутой конечной точки.
  • Отдельная конечная точка GET, которая возвращает текущий размер указанного файла загрузки.

Затем на стороне клиента вы начинаете загрузку. Если загрузка не удалась по какой-либо причине, вы запускаете GET для конечной точки размера файла и запускаете новый POST со смещением, равным первому байту после длины файла (и, очевидно, предоставляя только последнюю часть данных загрузки).

Это позволяет избежать потери одного байта загрузки независимо от того, не удалось ли установить соединение из-за ошибки в iOS, неправильной конфигурации сервера или просто случайного сбоя в сети. Более того, он, вероятно, также будет приемлемо работать с фоновой загрузкой в ​​NSURLSession.

person dgatwood    schedule 22.06.2017
comment
Спасибо @dgatwood. Я совсем забыл тебе ответить. Вы были правы, я достиг предельного времени выполнения на стороне сервера (определено как 60 секунд). Кроме того, ваше предложение довольно хорошее, и я уже определил задачу по его реализации (поскольку сервер, который я использую, имеет поддержку, чтобы сделать это правильно). - person Tiago Pereira; 24.07.2017