swiftswiftuiwidgetkitappintents

Is it possible to receive parameters in app intent constructor before execute the 'perform' method?


I'm trying to receive a parameter in my app intent struct constructor to perform an action using this parameter value, but the perform method executes before my own init being executed. By the way, the WidgetConfigurationIntent protocol forces me to have an empty init, even I already have my own constructor, so I need to have two constructors, and the first one that is executed is the empty constructor and then the perform method. So, my 'custom' constructor is executed only after these two. That way, I always receiving nil when I going to use the value of myParameter in my perform intent method.

Does someone have any idea how to solve it?

My intent is somethig like this:

struct ConfigurationAppIntent: WidgetConfigurationIntent {
    static var title: LocalizedStringResource = "Configuration"
    static var description = IntentDescription("This is an example widget.")
    
    var myParameter: MyCustomClass?
    
    init(myParameter: MyCustomClass?) {
        self.myParameter = myParameter
    }
    
    init() {}
    
    func perform() async throws -> some IntentResult {
        print("intent was executed")
        
        return .result()
    }
}

Solution

  • To handle actions, you can't use the WidgetConfigurationIntent, because this Intent type is to make configurations in your widget.

    To execute actions, your class need to extend from AppIntent.

    struct ExampleAppIntent: AppIntent {
        static var title: LocalizedStringResource = "Example"
        
        @Parameter(title: "parameter") var parameter: String?
        
        init(parameter: String?) {
            self.parameter = parameter
        }
        
        init() {}
        
        func perform() async throws -> some IntentResult {
            print("my parameter: \(parameter)")
            
            return .result()
        }
    }
    

    // In another file you can call it by the init

    Button(intent: ExampleAppIntent(parameter: "My value")) {
        Text("Execute")
    }
    

    Font: