我无法接收 UIViewController 设置为 URLSessionDelegate 的 HTTP 响应

Am unable to receive HTTP responses with UIViewController set as URLSessionDelegate

2018 年 5 月 3 日第 5 步添加了附加信息

我能够创建一个 URLSesion,构建一个包含要上传的文件的请求,并从我的应用程序中成功调用它。在我的服务器端,调用正确的脚本,保存上传的文件等。但是,我没有收到 HTTP 响应、数据等。

当 HTTP 响应函数在任务本身内时,实际上在没有委托的情况下也能正常工作。但是我现在正在尝试扩展功能并且在尝试实现委托时遗漏了一些东西。

修剪后的代码在下面,一切正常,除了将 UIViewController 设置为 URLSession 委托。只是想弄清楚为什么我的 UIViewController 没有收到 HTTP 响应。

下面是代码:

  1. UIViewController
  2. Class 创建上传会话 (UploadService)
  3. 扩展名 我想用来处理响应的 UIViewController
  4. 上一个任务执行时的外观。在我尝试实现委托之前。
  5. 使用 print 确认我的 UIViewConroller 是委托,但它仍然没有收到 HTTP 响应、数据或错误消息

UIViewController

class UploadInv : UIViewController {
    
    var xFile : XFile?

    ...create UI....

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

    override func viewWillAppear(_ animated: Bool) {
    ...
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        uploadService.uploadSession = uploadSession

    ... code the lays out all buttons, labels, etc...
    }

    @objc func buttonAction(sender: UIButton!) {
        guard let theButton = sender else { return}
        let myTag = theButton.tag
        
        switch myTag {
            //button to start upload  
            case ButtType.up.rawValue:
                uploadService.start(upFile: xFile!, script: "uploadOrig.pl", upLoadInvClass: self)
                uploadService.task?.resume()
            
            //button to select file to upload
            case ButtType.file.rawValue:
                ... file xFile with file info            
        }
    }

上传服务

class UploadService  {
    var uploadSession : URLSession!
    var task: URLSessionUploadTask?
    
    func start(upFile:  XFile, script: String, upLoadInvClass: UploadInv) {
        var request = upFile.makeUrlReq(upFile: upFile, script: script)
        
        task = uploadSession.uploadTask(with: request, from: request.httpBody!  )
        print("\(uploadSession.delegate)")
        task?.resume()
    }
}

分机

    extension UploadInv:  UIDocumentPickerDelegate, URLSessionDelegate {
        
        func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
            
     ... file xFile info for upload ....        
     ... http request created  ....             
        }
        
// Below are the three simple functions which I would handle 
// responses the server, but these never seem to get called.        

        func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
            if let err = error {
                print("Error: \(err.localizedDescription)")
            }
        }
        
        func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: (URLSession.ResponseDisposition) -> Void) {
                print("didReceive response")
                completionHandler(URLSession.ResponseDisposition.allow)
         }
         
         func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
           print("didReceive data")
             if let responseText = String(data: data, encoding: .utf8) {
                print(responseText)
             }
        }
    }

有效的预委托模型

class UploadService  {
    
    var uploadSession = URLSession.shared

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

            }
            }.resume()
    }
}

第 5 步:

task = uploadSession.uploadTask(with: request, from: request.httpBody!  )
        print("\(uploadSession.delegate)")
        task?.resume()

对于其他新手也卡在这个上面,结果要看的代表不止一个。有:

URLSessionTaskDelegate、URLSessionDataDelegate、URLSessionDownloadDelegate 等。所以很明显我用错了,可能掉进了“自动完成”的陷阱。尽管如此,我必须确保阅读更多有关该主题的文档。

感谢 Scott,他“passively/aggressively”给了我答案,here,同时还允许我“思考”。我的意思是作为一种恭维。他告诉我添加行:

assert(uploadSession.delegate! is URLSessionDataDelegate)