I'm trying to establish a persistent connection with an IMAP server so that whenever the server sends something over the stream, my app will be notified and be able to respond accordingly.
Here is what I have set up so far:
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")
}
}
}
How can I set up a persistent delegate method that receives data from the IMAP stream?
CodePudding user response:
You should conform to URLSessionStreamDelegate
instead of URLSessionDataDelegate
since you are creating a URLSessionStreamTask
not a URLSessionDataTask
.
The urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
method would only be called if you were using a URLSessionDataTask
.
The func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
is correctly called when closing the stream by calling closeRead()
and closeWrite()
on your URLSessionStreamTask
.