优点和缺点:Alamofire 并发与常规或建议的方法

Pros and Cons Alamofire Concurrency vs Regular or suggested method

提问人:Carlos Alvarado 提问时间:5/23/2023 最后编辑:HangarRashCarlos Alvarado 更新时间:5/24/2023 访问量:355

问:

有人可以向我解释一下 Alamofire 并发和 Alamofire 常规建议方法的优缺点吗? 并发方式

func getDataConcurrency() async throws -> SomeModel {
    let dataTask = AF.request("/getData")
        .validate()
        .serializingDecodable(SomeModel.self)
    let response = await dataTask.response
    
    switch response.result {
    case .success(let model):
        return SomeModel
    case .failure(let err):
        throw err
    }
}

Alamofire 的常规、默认或建议方法

func getDataRegularMethod(completion: @escaping (Result<SomeModel, AFError>) -> Void) {
    AF.request("/getData")
    .validate()
    .responseDecodable(of: SomeModel.self) { response in
        switch response.result {
        case .success(let someModel):
            completion(.success(someModel))
        case .failure:
            completion(.failure(.someAFError)
        }
    }
}

了解并选择最佳选项

Swift 并发 关闭 Alamofire

评论

0赞 HangarRash 5/23/2023
第一种使用现代 Swift 并发。第二种使用旧的过时的完成处理程序方法。有关详细信息,请阅读 Swift 书中的并发一章。
0赞 lorem ipsum 5/23/2023
观看 WWDC 中的“Meet async/await”

答:

2赞 Rob 5/23/2023 #1

就 Swift 并发的优点而言,一般来说:

  • 不需要完成处理程序(通常使代码更容易推理);
  • 不再需要任何类型;和switchResult
  • 它对取消有更优雅的支持。

在缺点方面:

  • 它需要以 iOS 13 或 macOS Catalina 或更高版本为目标的应用;
  • 它需要 Swift 5.6 或更高版本以及 Xcode 13.3.1 或更高版本(但这可能没有实际意义,因为截至 4 月,“提交给 App Store 的应用程序必须使用 Xcode 14.1 或更高版本构建”);
  • 如果你使用 Swift 并发,你可能希望整个项目使用 Swift 并发并停用 GCD 模式......通常不建议在同一项目中混合使用异步模式;和
  • 如果你不熟悉 Swift 并发、actors、-、类型等,那么就会有一点学习曲线。asyncawaitSendable

缺点往往比实际缺点更多的限制。底线,如果你使用 -,你可能应该使用。但是你可以随心所欲地做任何事情,并且保持一致(无论是传统的完成处理程序模式、Combine 还是 Swift 并发)。但 Swift 并发是新兴标准,所以如果你选择使用传统的完成处理程序模式,你可能需要一个非常有说服力的案例来做到这一点。asyncawait

现在,如果您已经在您的项目中采用了 - 并且只是想知道您是否也应该在 Alamofire 中采用这种模式,答案是,是的,您可能应该这样做。没有缺点,正如您将在下面看到的,它简化了您的代码。asyncawait


FWIW,您的 Swift 并发示例可以进一步简化:

func getDataConcurrency(for url: URL) async throws -> SomeModel {
    try await AF.request(url)
        .validate()
        .serializingDecodable(SomeModel.self, automaticallyCancelling: true)
        .value
}

如果请求成功,将返回该值。如果失败,将引发错误。如果取消任务,请求将自动取消。不需要完成处理程序或语句。switch


如果您对 Swift 并发及其优势的更多信息感兴趣,请参阅 WWDC 2021 视频 Meet async/await in Swift,以及该页面上的其他视频。

评论

0赞 Rob 5/24/2023
FWIW,我已经在 Alamofire 上打开了问题 #3727,建议真的应该默认为 ,而不是要求我们手动设置。我理解为什么他们默认为 ,因为 Xcode 13.2 中的支持很不稳定,但我相信这个问题已经解决了。敬请关注。automaticallyCancellingtruefalse
0赞 Carlos Alvarado 5/24/2023
在某些情况下,我添加开关案例的原因是因为我想从 API 中获取 response.data,该数据包含错误验证,但在其他情况下,我不需要该数据,我只是抛出错误,您向我展示的方式更实用,感谢您的快速响应,我只是想确保选择了最佳选项@rob
0赞 Rob 5/24/2023
@CarlosAlvarado - 反对意见本身不是。但是在 Swift 并发中几乎总是(寻找/案例)代码气味。枚举类型的目的是在完成处理程序代码中提供错误处理,并且是一个不合时宜的 Swift 并发代码库。我们大多数人都会在 AF 上做,然后检查各种属性,看看是否存在我们想要检测的 API 级条件以及可能的错误。但是 / switch 是一种反模式。switchswitchResult.success.failureResulttry awaitvalueSomeModelthrowsuccessfailure
0赞 Rob 5/24/2023
但是,嘿,随心所欲。我的答案是基于原始问题中的代码,其中 just 增加了语法噪音,没有提供任何附加值。也许你有一些需要它的例子(尽管我承认持怀疑态度......我在 Stack Overflow 上看到的大多数基于异步代码的开发人员都陷入了旧的、熟悉的模式),但我们大多数人已经在很大程度上淘汰了 Swift 并发中的 on 类型。switchResultswitchResult