URLSession 数据任务超时错误
URLSession dataTask timeout error
我目前在尝试 post 数据到我的网络服务器时遇到了一些关于 URLSession 的问题。然而,这非常有效。似乎不起作用的是我设置的超时。这对我的整个应用程序来说相当重要,因为我不希望用户永远 'loading',没有任何类型的错误消息。这是我的代码:
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 秒,然后 return 出现错误(警报)。我怎样才能做到这一点?我觉得我已经尝试了所有可能的方法,只是通过配置URLSessionConfiguration
,并设置.timeoutInterval
。
不胜感激!
超时应该总是几分钟,而不是二十秒。在糟糕的蜂窝连接上进行 DNS 查找可能需要二十或三十秒,使用二十秒超时意味着在糟糕的网络上,您的应用程序将完全无法使用。
您在 UI 中处理此问题的方式应该完全独立于网络代码。启动请求并同时创建和启动计时器。如果在计时器触发时您的会话委托尚未收到 ...didReceiveResponse:...
调用,则显示 "slow network" UI,但让网络请求继续直到失败。
此外,如果您的请求是幂等的(也就是说,如果发出两次请求是安全的),您可以考虑使用间隔很短(例如 5 秒)的第二个计时器,并且如果您还没有得到在那段时间内 didReceiveResponse:
调用,并行启动第二个请求。如果第二个任务在你的 20 秒计时器触发时没有得到响应,请取消它。如果首先得到响应,则取消原始请求。这有助于减少数据包丢失对用户感知延迟的影响。
我目前在尝试 post 数据到我的网络服务器时遇到了一些关于 URLSession 的问题。然而,这非常有效。似乎不起作用的是我设置的超时。这对我的整个应用程序来说相当重要,因为我不希望用户永远 'loading',没有任何类型的错误消息。这是我的代码:
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 秒,然后 return 出现错误(警报)。我怎样才能做到这一点?我觉得我已经尝试了所有可能的方法,只是通过配置URLSessionConfiguration
,并设置.timeoutInterval
。
不胜感激!
超时应该总是几分钟,而不是二十秒。在糟糕的蜂窝连接上进行 DNS 查找可能需要二十或三十秒,使用二十秒超时意味着在糟糕的网络上,您的应用程序将完全无法使用。
您在 UI 中处理此问题的方式应该完全独立于网络代码。启动请求并同时创建和启动计时器。如果在计时器触发时您的会话委托尚未收到 ...didReceiveResponse:...
调用,则显示 "slow network" UI,但让网络请求继续直到失败。
此外,如果您的请求是幂等的(也就是说,如果发出两次请求是安全的),您可以考虑使用间隔很短(例如 5 秒)的第二个计时器,并且如果您还没有得到在那段时间内 didReceiveResponse:
调用,并行启动第二个请求。如果第二个任务在你的 20 秒计时器触发时没有得到响应,请取消它。如果首先得到响应,则取消原始请求。这有助于减少数据包丢失对用户感知延迟的影响。