I want to store a task instance so that I can later on check for it's result, to see if it successfully completed or if it thrown an error.
I'm not sure of two things:
How do I return from a Task? I know about the Result<Success,Fail> enum, but I'm not sure I'm using it correct.
I get a compilation error when I try to store the task, because the types don't match
my code:
class MessageDispatcher {
private var listeningForMessagesTask: Task<Void,InvalidDataError>
func listenForMessages() {
**self.listeningForMessagesTask = Task.detached(priority: .background) {** // ERROR Line
// with the message: Cannot assign value of type 'Task<Void, Error>' to type 'Task<Void, ///. InvalidDataError>'
var isDone = false
repeat {
guard let (message, done) = try await self.connection.receive() else {
return Result.failure(InvalidDataError.BadServer)
}
isDone = done
DispatchQueue.main.async {
self.rooms[0].chat += message
}
} while !isDone
print("Done!")
}
}
enum InvalidDataError : Error {
case NoData
case BadEncoding
case BadServer
}
The return type of the operation closure must be the generic type Success. In your declaration of listeningForMessagesTask, you've specified Void as the concrete type for Success:
private var listeningForMessagesTask: Task<Void,InvalidDataError>
// ^^^^
Therefore, the return type of the operation closure passed to Task.detached(priority: .background) must be Void, but you're trying to return an instance of Result:
return Result.failure(InvalidDataError.BadServer)
Here's what you should do instead:
Change the type of listeningForMessagesTask to Task<Void, Error> and throw the error instead of trying to return it wrapped in a Result:
Thanks Peter, you've been very generous with the response and I really appreciate that. I have a better understanding of it now, and I understand that I can basically only return the specified type of Success (which as pointed out by you, was Void).
I guess then, that in the background, aka behind the scenes, the static detached method will take whatever I throw in the closure and manipulate that back into a Result<Void,Error> basically returning back a Failure (. failure(_)) for me, if my closure throws.
Hope I got it right, this time. And thank you for your generosity! You've explained it like a pro.