# Control Flow Patterns How to implement loops, conditionals, and menus in Shortcuts. ## Overview Control flow actions use two key parameters: - **GroupingIdentifier**: A UUID that links related actions (start, middle, end) - **WFControlFlowMode**: An integer indicating the action's role - `0` = Start (begin block) - `1` = Middle (else, case) - `2` = End (close block) **Important**: `WFControlFlowMode` must be an ``, not a ``. --- ## Repeat Count Repeat a block of actions a specific number of times. ### Structure | Mode | Action | Description | |------|--------|-------------| | 0 | Start | Begin repeat, set count | | 2 | End | Close repeat block | ### Template ```xml WFWorkflowActionIdentifier is.workflow.actions.repeat.count WFWorkflowActionParameters GroupingIdentifier REPEAT-GROUP-UUID WFControlFlowMode 0 WFRepeatCount 5 WFWorkflowActionIdentifier is.workflow.actions.repeat.count WFWorkflowActionParameters UUID END-ACTION-UUID GroupingIdentifier REPEAT-GROUP-UUID WFControlFlowMode 2 ``` ### Accessing Repeat Index Inside the loop, reference the current index using the End action's UUID: ```xml attachmentsByRange {0, 1} OutputUUID END-ACTION-UUID OutputName Repeat Index Type ActionOutput ``` --- ## Repeat with Each (For Each) Iterate over each item in a list. ### Structure | Mode | Action | Description | |------|--------|-------------| | 0 | Start | Begin loop, specify input list | | 2 | End | Close loop | ### Template ```xml WFWorkflowActionIdentifier is.workflow.actions.repeat.each WFWorkflowActionParameters GroupingIdentifier FOREACH-GROUP-UUID WFControlFlowMode 0 WFInput Value OutputUUID LIST-SOURCE-UUID OutputName List Type ActionOutput WFSerializationType WFTextTokenAttachment WFWorkflowActionIdentifier is.workflow.actions.repeat.each WFWorkflowActionParameters UUID END-ACTION-UUID GroupingIdentifier FOREACH-GROUP-UUID WFControlFlowMode 2 ``` ### Accessing Current Item Reference the current item using the Start action's UUID with OutputName "Repeat Item": ```xml attachmentsByRange {0, 1} OutputUUID START-ACTION-UUID OutputName Repeat Item Type ActionOutput ``` --- ## Conditional (If/Otherwise) Execute different actions based on a condition. ### Structure | Mode | Action | Description | |------|--------|-------------| | 0 | If | Start conditional, define condition | | 1 | Otherwise | Else branch | | 2 | End If | Close conditional | ### Template ```xml WFWorkflowActionIdentifier is.workflow.actions.conditional WFWorkflowActionParameters GroupingIdentifier IF-GROUP-UUID WFControlFlowMode 0 WFCondition Equals WFInput Value OutputUUID VALUE-TO-TEST-UUID OutputName Text Type ActionOutput WFSerializationType WFTextTokenAttachment WFConditionalActionString expected value WFWorkflowActionIdentifier is.workflow.actions.conditional WFWorkflowActionParameters GroupingIdentifier IF-GROUP-UUID WFControlFlowMode 1 WFWorkflowActionIdentifier is.workflow.actions.conditional WFWorkflowActionParameters GroupingIdentifier IF-GROUP-UUID WFControlFlowMode 2 ``` ### Condition Types | WFCondition Value | Description | |-------------------|-------------| | `Equals` | Value equals comparison | | `Does Not Equal` | Value does not equal | | `Contains` | String contains substring | | `Does Not Contain` | String does not contain | | `Begins With` | String starts with | | `Ends With` | String ends with | | `Is Greater Than` | Number comparison | | `Is Less Than` | Number comparison | | `Is Between` | Number in range | | `Has Any Value` | Not empty | | `Does Not Have Any Value` | Is empty | --- ## Choose from Menu Present a menu of options and execute different actions based on the user's choice. ### Structure | Mode | Action | Description | |------|--------|-------------| | 0 | Menu | Define menu with items | | 1 | Case | One case per menu item | | 2 | End Menu | Close menu | ### Template ```xml WFWorkflowActionIdentifier is.workflow.actions.choosefrommenu WFWorkflowActionParameters GroupingIdentifier MENU-GROUP-UUID WFControlFlowMode 0 WFMenuPrompt Choose an option: WFMenuItems Option 1 Option 2 Option 3 WFWorkflowActionIdentifier is.workflow.actions.choosefrommenu WFWorkflowActionParameters GroupingIdentifier MENU-GROUP-UUID WFControlFlowMode 1 WFMenuItemTitle Option 1 WFWorkflowActionIdentifier is.workflow.actions.choosefrommenu WFWorkflowActionParameters GroupingIdentifier MENU-GROUP-UUID WFControlFlowMode 1 WFMenuItemTitle Option 2 WFWorkflowActionIdentifier is.workflow.actions.choosefrommenu WFWorkflowActionParameters GroupingIdentifier MENU-GROUP-UUID WFControlFlowMode 1 WFMenuItemTitle Option 3 WFWorkflowActionIdentifier is.workflow.actions.choosefrommenu WFWorkflowActionParameters GroupingIdentifier MENU-GROUP-UUID WFControlFlowMode 2 ``` ### Important Notes 1. **Case order must match WFMenuItems order** - Each case (mode 1) must appear in the same order as the items in WFMenuItems array 2. **WFMenuItemTitle must exactly match** - The case title must exactly match the corresponding item in WFMenuItems 3. **One case per item** - You need exactly one case action for each menu item --- ## Nesting Control Flow Control flow blocks can be nested. Each nested block needs its own unique GroupingIdentifier: ```xml WFWorkflowActionIdentifier is.workflow.actions.repeat.count WFWorkflowActionParameters GroupingIdentifier OUTER-LOOP-UUID WFControlFlowMode 0 WFRepeatCount 3 WFWorkflowActionIdentifier is.workflow.actions.conditional WFWorkflowActionParameters GroupingIdentifier INNER-IF-UUID WFControlFlowMode 0 WFWorkflowActionIdentifier is.workflow.actions.conditional WFWorkflowActionParameters GroupingIdentifier INNER-IF-UUID WFControlFlowMode 1 WFWorkflowActionIdentifier is.workflow.actions.conditional WFWorkflowActionParameters GroupingIdentifier INNER-IF-UUID WFControlFlowMode 2 WFWorkflowActionIdentifier is.workflow.actions.repeat.count WFWorkflowActionParameters GroupingIdentifier OUTER-LOOP-UUID WFControlFlowMode 2 ``` --- ## Common Mistakes 1. **Using string instead of integer for WFControlFlowMode** - Wrong: `0` - Right: `0` 2. **Mismatched GroupingIdentifier** - All parts of a control flow block must share the same GroupingIdentifier 3. **Missing End action** - Every start (mode 0) must have a corresponding end (mode 2) 4. **Wrong order in menu cases** - Cases must appear in the same order as WFMenuItems 5. **Referencing wrong UUID for loop items** - Repeat Item uses the **start** action's UUID - Repeat Index uses the **end** action's UUID