2016-10-21 10 views
0

В настоящее время у меня возникают некоторые проблемы, связанные с URLSession, при попытке отправить данные на мой веб-сервер. Это, однако, прекрасно работает. Что, похоже, не работает, это тайм-аут, который я установил. Это очень важно для всего моего приложения, так как я не хочу, чтобы пользователи «загружались» навсегда без каких-либо сообщений об ошибках. Вот мой код:URLSession dataTask timeout error

var request = URLRequest(url: URL(string: "https://www.mywebsite.com/file.php")!, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 20) 

let urlconfig = URLSessionConfiguration.default 
urlconfig.timeoutIntervalForRequest = 20 
urlconfig.timeoutIntervalForResource = 20 

request.httpMethod = "POST" 
let session = URLSession(configuration: urlconfig, delegate: self, delegateQueue: nil)//URLSession.shared 
let body = "receiver=\(receiverID)" 
request.httpBody = body.data(using: String.Encoding.utf8, allowLossyConversion: true) 
request.timeoutInterval = 20 

session.dataTask(with: request) {data, response, err in 
    if err == nil { 
     do { 
      let jsonResult:NSDictionary? = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary 
      let jsonComp = jsonResult?.value(forKey: "completion") as! String 
      if jsonComp == "done" { 
      } else { 
      } 
     }catch{} 
    } else { 
    } 
}.resume() 

Я просто хочу установить тайм-аут на 20 секунд, а затем вернуть ошибку (предупреждение). Как я могу это сделать? Я чувствую, что я попробовал все возможное, просто сконфигурировав URLSessionConfiguration и установив .timeoutInterval.

Справка была бы принята с благодарностью!

+0

Уже ясно, что этот вопрос касается Swift по тегам. В чем смысл «Swift» в названии? –

+0

@LeoNatan Скорее не нужен -1 мой пост из-за того, что вы считаете, что я ошибаюсь, чтобы поставить «Swift» в заголовок. Но чтобы ответить на ваш вопрос, это просто потому, что я просто хочу указать, что язык Swift. Что-то я всегда делаю. – askaale

+1

Я выступаю против такого поведения. Я буду обсуждать такие вопросы, извините - мне все равно, наклоняюсь ли я на ветряные мельницы. http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles –

ответ

3

Таймауты должны всегда длиться несколько минут, а не двадцать секунд. Может потребоваться двадцать или тридцать секунд, чтобы выполнить поиск DNS по плохой сотовой связи, а использование двадцать второго тайм-аута означает, что в плохой сети ваше приложение будет полностью непригодным для использования.

Способ, которым вы справляетесь с этим в пользовательском интерфейсе, должен быть полностью независим от сетевого кода. Запустите запрос и одновременно создайте и запустите таймер. Если ваш делегат сеанса не получил вызов ...didReceiveResponse:... к моменту запуска таймера, покажите «медленный сетевой» интерфейс, но пусть сетевой запрос будет продолжаться до тех пор, пока он не сработает.

Кроме того, если ваши запросы являются идемпотентными (то есть, если запрос дважды является безопасным), вы можете подумать о том, чтобы иметь второй таймер с очень коротким интервалом (например, 5 секунд), и если вы не получили didReceiveResponse:, вызовите второй запрос параллельно. Если эта вторая задача не получит ответа к моменту запуска вашего двадцать второго таймера, отмените его. Если он сначала получит ответ, отмените исходный запрос. Это может помочь уменьшить влияние потери пакетов на задержку, вызванную пользователем.

+0

Хорошо, спасибо, что разобрали это. Я понял! Однако, вы говорите мне, что после x суммы времени запрос в конечном итоге не удастся? Поэтому, если я создаю предупреждение в 'if error == nil {} else {print («что-то здесь»)}, консоль напечатает «Что-то здесь»? А также, могу ли я просто отменить запрос после x секунд, через мой таймер? – askaale

+0

В конце концов, он может выйти из строя, и в этом случае да, вы получите вызов с ошибкой, отличной от нуля. Я думаю, что по умолчанию стоит отказаться от 90 секунд без получения одного байта данных, но я мог бы помнить, что число ошибочно. По умолчанию не должно быть максимального общего времени, потому что это приведет к сбою более длинных загрузок. – dgatwood

+0

Вы можете в конечном итоге отменить запрос, но вы, вероятно, не должны. Общая рекомендация Apple заключается в том, чтобы позволить пользователю отменить запрос, если пользователь больше не заботится о данных. В противном случае предположим, что пользователь в конечном итоге хочет получить данные, даже если это занимает много времени. – dgatwood