【发布时间】:2017-10-19 15:05:00
【问题描述】:
我是 iOS/Swift 开发的新手,我正在开发一个向 REST API 发出多个请求的应用程序。以下是其中一个检索“消息”的调用示例:
func getMessages() {
let endpoint = "/api/outgoingMessages"
let parameters: [String: Any] = [
"limit" : 100,
"sortOrder" : "ASC"
]
guard let url = createURLWithComponents(endpoint: endpoint, parameters: parameters) else {
print("Failed to create URL!")
return
}
do {
var request = try URLRequest(url: url, method: .get)
let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
if let error = error {
print("Request failed with error: \(error)")
// TODO: retry failed request
} else if let data = data, let response = response as? HTTPURLResponse {
if response.statusCode == 200 {
// process data here
} else {
// TODO: retry failed request
}
}
}
task.resume()
} catch {
print("Failed to construct URL: \(error)")
}
}
当然,此请求失败的原因有很多(服务器无法访问、请求超时、服务器返回 200 以外的值等)。如果我的请求失败,我希望能够重试它,甚至可能在下一次尝试之前有延迟。我在 Apple 的文档中没有看到任何关于这种情况的指导,但我发现了一些关于 SO 的相关讨论。不幸的是,这两个都是几年前的,并且在我从未使用过的 Objective-C 中。在 Swift 中做这样的事情有什么常见的模式或实现吗?
【问题讨论】:
-
这取决于,这些请求是否与 UI 相关联? (即您是否需要来自服务器的数据来显示内容)。还是只是需要将数据从应用程序存储到服务器的后端逻辑
-
@TNguyen 简短的回答是两者兼而有之;一些请求仅用于填充数据库,而另一些则需要更新 UI
-
对于 UI 来说,有很多方法可以处理它,但我觉得一般标准是让用户知道他们没有互联网,并允许用户在何时刷新他们这样做(或者您可以使用可达性并不断收听以等待网络连接可用,然后提出您的请求,我确定还有许多其他方法)。至于后端,您是否需要尽可能地使数据库中的数据保持最新?或者如果它晚一点出现,这不是什么大不了的事。你可以看到这在重试逻辑中扮演着怎样的重要角色
-
@TNguyen 感谢您的建议。我现在实际上正在使用可达性来了解我是否有连接。我的问题中显示的示例请求是由服务器发送的推送通知触发的。用户可能没有查看应用程序中显示该数据的部分,但期望数据将几乎立即被提取并插入到数据库中。
-
我不再过多地处理远程通知,但是您不能通过远程通知推送您需要的数据而不是调用服务器吗?此外,如果您需要立即通过对服务器的请求插入数据库的部分,那么我可能会在后台使用一个计时器,就像您在 OP 中所说的那样一遍又一遍地重试它。但明显的问题是当用户离开或终止应用程序时,在这种情况下你很不走运,并且当他们再次打开应用程序时必须重新开始重试。 (也许像
applicationDidBecomeActive
标签: ios swift nsurlsession nsurlsessiondatatask retry-logic