不确定我的代码中是否需要以下几行(设置委托和委托队列)用于 URLSession?

Unsure if I need the following lines (setting delegate and delegateQueue) in my code, for URLSessions?

虽然我编写的代码运行良好,但其中很多代码都基于许多不同的教程。我现在处于“清理阶段”,所以想知道我是否需要下面的第 2 部分?

在我的 UIViewController (myMain) 的顶部,我有以下几行:

1- let uploadService = UploadService()
2- lazy var uploadSession: URLSession = {
       let configuration = URLSessionConfiguration.default
       return URLSession(configuration: configuration, delegate: self, 
       delegateQueue: .main)
    }()

稍后在我的代码中,当需要发送 POST 请求时,我从 myView 中的“上传”按钮开始:

uploadService.start(upFile: xFile!, script: "uploadOrig.pl", myView: self)

上传服务是:

class UploadService  {
    
    var uploadSession = URLSession.shared

    func start(upFile: XFile, script: String, myView: UploadInv) {
        var request = upFile.makeUrlReq(upFile: upFile, script: script)
        
        uploadSession.uploadTask(with: request, from: request.httpBody  )
        { (data, response, error) in
            if let response = response {
               myView.upResp(resp: response) }
            
            if let error = error {
                myView.upErr(error: error) }
            
            if let data = data {
                myView.upData(data: data) }
        }.resume()
    }}

所有在 myView 中由 UploadClass 调用的方法都包含在 :

    DispatchQueue.main.async { [self] in
    do { ... }

所以我的不确定性是:

处理上传的 class 有自己的完成处理程序,因此我认为我不需要设置委托。同样,Swift 会自动在后台线程上运行它。

一切正常,无论我是否注释掉上面的第 2 部分。但这并不意味着这两种方式都是正确的。

我必须设置委托和委托队列吗?或者我可以将其注释掉并允许上传吗?

有两个单独的问题:

  1. 你需要uploadSession在你有它的地方定义吗?

    没有。如果您可以将其注释掉并且您的代码仍然可以编译,则意味着您没有在任何地方使用它并且您可以而且应该完全删除它。您不希望在您的项目中使用未使用的代码。

    此外,如果您确实需要一个自定义 URLSession 实例,似乎 UploadService 可能是一个更合乎逻辑的地方来保留它。我们通常争取高度内聚的对象和清晰的职责分离,您可能希望将所有网络代码保留在网络层中,而不是分散在您的项目中。

  2. UploadService 有自己的 URLSession。您应该使用 .shared 还是使用自己的配置和委托定义自己的 URLSession 实例?

    如果您根本不需要自定义 URLSession,那么使用 .shared 就可以了,而且最简单。如果您需要这些功能之一,我只建议引入您自己的自定义 URLSession 实例。

    但是,如果您没有实现任何委托方法,那么,不,您不需要(也不想)引入一个什么都不做的委托。它只会让代码更难阅读。


那么,您什么时候想使用自己的 URLSession 实例?有多种情况。请参阅 the documentation 中的“URL 会话类型”和“使用会话委托”,了解您何时可以这样做的几个示例。就个人而言,我只在执行后台 URLSession 请求时使用自定义 URLSession 实例,当我离开应用程序时需要继续 运行 。或者我需要进度报告。或者在我想要自定义 URLSessionConfiguration.

的极少数情况下

但是手动实例化 URLSession 实例需要更多的内务处理(例如,您必须在完成它们后“完成并使它们无效”,否则就会泄漏)。 delegate-based URLSession 比 completion-handler 或 Swift 并发再现稍微复杂一点,所以只在需要的地方做。

Delegate-based URLSession 提供了更丰富的功能集(重定向的特殊处理、自定义身份验证质询身份验证、进度报告等),但它的代价是代码更加复杂。我建议只在需要额外功能的地方引入这种复杂性。