我不知道您的完成闭包看起来如何,但您可以考虑使用带有关联值的 enum 结果 (here you can read more about associated values)。
如果您像这样创建enum:
enum ClosureResult {
case success([String])
case failure([String], [Error])
}
您可以根据网络查找是失败还是成功返回不同的值。请注意,在我的 failure 案例中,我将一组 Error 对象作为第二个参数传递,我不知道这是否适合您,但这只是为了说明您可以传递多个参数作为回报.
如果您随后使用 ClosureResult 作为完成闭包的返回值,则可以在返回时在自己的块中对其执行 switch 并根据该值采取行动。
所以,你的函数可能看起来像这样:
func yourFunction(items: [String], completion: (ClosureResult) -> Void) {
var completedItems = [String]()
var failedItems = [Error]()
for item in items {
//Do your network magic here
//if it succeeds add it to completedItems
//if it fails, add it to failedItems
}
//did we encounter any failures?
if failedItems.count > 0 {
//yes we did, return a .failure then
let failure = ClosureResult.failure(completedItems, failedItems)
completion(failure)
} else {
//no...return .success
let success = ClosureResult.success(completedItems)
completion(success)
}
}
然后你可以像这样使用它:
let items = ["a", "b", "c"]
yourFunction(items: items) { result in
switch result {
case .success(let okItems):
print(okItems)
case .failure(let okItems, let failedItems):
print(failedItems)
}
}
更新
在你的评论中你问:
我唯一担心的是,在您的示例中,网络请求在“a”和“c”上成功但不是“b”,关闭结果包含有关哪个项目失败的任何信息。在 ClosureResult 对象中返回项目的元组和该项目的网络结果而不只是字符串是否合理?
是的,这是有道理的。我只是以String 和Error 为例,但您也可以使用自己的类。
我想,我要做的是,我会创建一个简单的类并返回它,而不是使用元组。
例如:
struct ClosureError {
let item: String
let error: Error
}
然后你的 ClosureResult 枚举可以使用它:
enum ClosureResult {
case success([String])
case failure([String], [ClosureError])
}
在您的yourFunction 中遇到故障时,您需要创建ClosureError 的新实例:
...
var failedItems = [ClosureError]()
...
for item in items {
//Do your network magic here
//if it succeeds add it to completedItems
//if it fails, add it to failedItems
let error = //create the error
let closureFailure = ClosureFailure(item, error)
failedItems.append(closureFailure)
}
...
最后,在您的switch 中,您会知道哪些项目失败了:
let items = ["a", "b", "c"]
yourFunction(items: items) { result in
switch result {
case .success(let okItems):
print(okItems)
case .failure(let okItems, let failedItems):
for closureError in failedItems {
print("item: \(closureError.item) has failed with error \(closureError.error)"
}
}
}
您可能应该为各个部分找出一些更好的名称:)
希望有意义并且可以使用。