It's easier to show an example than trying to explain it, will use CoreData as context:
Given NSManagedObjectContext
's perform()
function (removed unnecessary parts of the signature)
extension NSManagedObjectContext {
public func perform<T>(_ block: @escaping () throws -> T) async rethrows -> T
}
I want to write a wrapper for MOC that calls such function, for example.
class Persistence {
func read<T>(_ block: @escaping (NSManagedObjectContext) throws -> T) async rethrows -> T { // 1.
return try await container.viewContext.perform(block) // 2.
}
}
So that i can use it such as:
try await persistence.read { moc in
let repo = Repository(context: moc)
...
}
Now the problem is that given the closure signature required by perform
() throws -> T
(see // 1.)
i can't obviously pass a closure of type (NSManagedObjectContext) throws -> T
(see // 2.).
Question:
Is there a pattern that would allow me to do such a thing in Swift? Or a concurrency safe alternative to perform
?
If I understand you correctly this should work
func read<T>(_ block: @escaping (NSManagedObjectContext) throws -> T) async rethrows -> T {
let moc = container.viewContext // or some background context
return try await moc.perform { try block(moc) } // 2.
}