I would like to create a closure type that is always called on the main thread using the new parameter packs introduced in Swift 5.9. E.g.
protocol Repository {
func loadData(completion: MainClosure<Result<String, Error>>)
}
class MockRepository: Repository {
func loadData(completion: MainClosure<Result<String, Error>>) {
DispatchQueue.global().async {
// Load some data...
completion(.success("foo")) // Calls on the main thread
}
}
}
This is my current implementation, but I get 2 errors.
public struct MainClosure<each T> {
private let closure: (repeat each T) -> Void
public init(_ closure: @escaping (repeat each T) -> Void) {
self.closure = closure // Error: Type of expression is ambiguous without a type annotation
}
public func callAsFunction(_ parameter: repeat each T) -> Void {
DispatchQueue.main.async {
self.closure(each parameter) // Error: Cannot pass value pack expansion to non-pack parameter of type 'repeat each T'
}
}
}
If I don't define the init
method the compiler manages to do it for me, so there is some way, but I need to define it as public
.
How can I resolve these issues to a) store the closure
, b) pass the parameters to it from callAsFunction
?