Reputation: 7524
I have a SwiftUI component with a button, which I want to be used in various places. When the button is executed, a different action should be performed depending on the view.
One solution is that I pass a ViewModel down to the component. However, the solution doesn't scale that well with different ViewModels.
The alternative to work with a callback I don't find so nice either. Because the component is very deep from the hierarchy.
My idea was to create a CommandAction class. However, I fail at the method signature.
My idea was this class.
class CommandActions {
// MARK: Lifecycle
init(action: @escaping (( _ parameter1: String) async throws -> String)) {
self.action = action
}
// MARK: Internal
let action: ( _ parameter1: String) async throws -> String
}
This function should be execute.
private func doSomeAction(parameter1: String) async throws -> String {
await Task.sleep(seconds: 1)
return "Some Result"
}
When I want to init the class, I got a failure.
CommandActions(action: doSomeAction(parameter1: "test"))
The failure is: Cannot convert value of type 'String' to expected argument type '(String) async throws -> String'
I tried different variations but I don't get it. The goal is to only call something like this in the SwiftUI class: commandActions.action
Upvotes: 10
Views: 8928
Reputation: 7524
Thanks for the comment, I found the solution I was looking for.
public class CommandActions {
// MARK: Lifecycle
public init(action: @escaping () async -> Void) {
self.action = action
}
// MARK: Public
public let action: () async -> Void
}
Init the commands
public func getCommands() -> CommandActions {
CommandActions { [self] in
await myFunction()
}
}
And the function
private func myFunction() async {
// do some stuff here
}
Upvotes: 18