未调用 URLSession streamTask 的委托方法

Delegate Methods for URLSession streamTask Not Called

我正在尝试与 IMAP 服务器建立持久连接,以便每当服务器通过流发送内容时,我的应用程序都会收到通知并能够做出相应响应。

这是我到目前为止的设置:

class Mailer: NSObject, URLSessionDataDelegate{
  static let shared = Mailer()
  var stream: URLSessionStreamTask!
  var session: URLSession!

  override init(){
    super.init()

    session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: .main)
  
    //Initializing the connection should initiate a server greeting
    stream = session.streamTask(withHostName: "imap.gmail.com", port: 993)
    stream.startSecureConnection()
    stream.resume()

    //If I do a readData immediately here, I get a response, but none of the delegate methods fire
    Task{
      let (data, _) = try! await stream.readData(ofMinLength: 0, maxLength: 100000, timeout: 60)

      if let data = data, let response = String(data: data, encoding: .ascii){
        print(response) //This shows the IMAP server's greeting
      }
    }
  }
  
  func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
    //I think this should fire with the initial server response
    print("urlSession didReceive")
    print("task data: %@", data as NSData)
  }

  func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    //Nothing logs here
    print("urlSession didError")
      if let error = error as NSError? {
        print(error)
          print("task error: %@ / %d", error.domain, error.code)
      } else {
          print("task complete")
      }
  }
}

如何设置从 IMAP 流接收数据的持久委托方法?

您应该遵循 URLSessionStreamDelegate 而不是 URLSessionDataDelegate,因为您创建的是 URLSessionStreamTask 而不是 URLSessionDataTask

只有在使用 URLSessionDataTask 时才会调用 urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) 方法。

通过在 URLSessionStreamTask 上调用 closeRead()closeWrite() 关闭流时正确调用 func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)