Quick timer
A shortcut that lets you choose a timer duration, waits, and then sends a notification.
What you'll learn
- Control flow with
menu - Variables and bindings with
constandlet - String interpolation with
${} - Scripting actions, including
Scripting.wait - Notification actions, including
Notification.showNotificationandNotification.showAlert
Source
import Scripting;
import Notification;
shortcut {
name: "Quick Timer",
description: "Choose a duration and get notified when time is up",
}
const label = "Timer";
menu "How long?" {
case "1 minute" {
Scripting.wait(60);
Notification.showNotification("Your 1-minute timer is done!", label);
}
case "5 minutes" {
Scripting.wait(300);
Notification.showNotification("Your 5-minute timer is done!", label);
}
case "10 minutes" {
Scripting.wait(600);
Notification.showNotification("Your 10-minute timer is done!", label);
}
}
Notification.showAlert("Timer started!");<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>WFWorkflowClientVersion</key>
<string>1</string>
<key>WFWorkflowHasOutputFallback</key>
<false/>
<key>WFWorkflowHasShortcutInputVariables</key>
<false/>
<key>WFWorkflowIcon</key>
<dict>
<key>WFWorkflowIconGlyphNumber</key>
<integer>59511</integer>
<key>WFWorkflowIconStartColor</key>
<integer>4274264319</integer>
</dict>
<key>WFWorkflowImportQuestions</key>
<array/>
<key>WFWorkflowInputContentItemClasses</key>
<array/>
<key>WFWorkflowMinimumClientVersion</key>
<integer>900</integer>
<key>WFWorkflowMinimumClientVersionString</key>
<string>900</string>
<key>WFWorkflowName</key>
<string>Quick Timer</string>
<key>WFWorkflowTypes</key>
<array>
<string>NCWidget</string>
<string>WatchKit</string>
</array>
<key>WFWorkflowActions</key>
<array>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.gettext</string>
<key>UUID</key>
<string>00000000-0000-0000-0000-000000000000</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFTextActionText</key>
<string>Timer</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.setvariable</string>
<key>UUID</key>
<string>00000000-0000-0000-0000-000000000001</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFVariableName</key>
<string>label</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.choosefrommenu</string>
<key>UUID</key>
<string>00000000-0000-0000-0000-000000000003</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFControlFlowMode</key>
<integer>0</integer>
<key>WFMenuPrompt</key>
<string>How long?</string>
<key>WFMenuItems</key>
<array>
<string>1 minute</string>
<string>5 minutes</string>
<string>10 minutes</string>
</array>
<key>GroupingIdentifier</key>
<string>00000000-0000-0000-0000-000000000002</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.choosefrommenu</string>
<key>UUID</key>
<string>00000000-0000-0000-0000-000000000004</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFControlFlowMode</key>
<integer>1</integer>
<key>WFMenuItemTitle</key>
<string>1 minute</string>
<key>WFMenuItemAttributedTitle</key>
<string>1 minute</string>
<key>GroupingIdentifier</key>
<string>00000000-0000-0000-0000-000000000002</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.delay</string>
<key>UUID</key>
<string>00000000-0000-0000-0000-000000000005</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFDelayTime</key>
<integer>60</integer>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.notification</string>
<key>UUID</key>
<string>00000000-0000-0000-0000-000000000006</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFNotificationActionBody</key>
<string>Your 1-minute timer is done!</string>
<key>WFNotificationActionTitle</key>
<dict>
<key>WFSerializationType</key>
<string>WFTextTokenString</string>
<key>Value</key>
<dict>
<key>string</key>
<string></string>
<key>attachmentsByRange</key>
<dict>
<key>{0, 1}</key>
<dict>
<key>Type</key>
<string>Variable</string>
<key>VariableName</key>
<string>label</string>
</dict>
</dict>
</dict>
</dict>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.choosefrommenu</string>
<key>UUID</key>
<string>00000000-0000-0000-0000-000000000007</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFControlFlowMode</key>
<integer>1</integer>
<key>WFMenuItemTitle</key>
<string>5 minutes</string>
<key>WFMenuItemAttributedTitle</key>
<string>5 minutes</string>
<key>GroupingIdentifier</key>
<string>00000000-0000-0000-0000-000000000002</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.delay</string>
<key>UUID</key>
<string>00000000-0000-0000-0000-000000000008</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFDelayTime</key>
<integer>300</integer>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.notification</string>
<key>UUID</key>
<string>00000000-0000-0000-0000-000000000009</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFNotificationActionBody</key>
<string>Your 5-minute timer is done!</string>
<key>WFNotificationActionTitle</key>
<dict>
<key>WFSerializationType</key>
<string>WFTextTokenString</string>
<key>Value</key>
<dict>
<key>string</key>
<string></string>
<key>attachmentsByRange</key>
<dict>
<key>{0, 1}</key>
<dict>
<key>Type</key>
<string>Variable</string>
<key>VariableName</key>
<string>label</string>
</dict>
</dict>
</dict>
</dict>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.choosefrommenu</string>
<key>UUID</key>
<string>00000000-0000-0000-0000-000000000010</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFControlFlowMode</key>
<integer>1</integer>
<key>WFMenuItemTitle</key>
<string>10 minutes</string>
<key>WFMenuItemAttributedTitle</key>
<string>10 minutes</string>
<key>GroupingIdentifier</key>
<string>00000000-0000-0000-0000-000000000002</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.delay</string>
<key>UUID</key>
<string>00000000-0000-0000-0000-000000000011</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFDelayTime</key>
<integer>600</integer>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.notification</string>
<key>UUID</key>
<string>00000000-0000-0000-0000-000000000012</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFNotificationActionBody</key>
<string>Your 10-minute timer is done!</string>
<key>WFNotificationActionTitle</key>
<dict>
<key>WFSerializationType</key>
<string>WFTextTokenString</string>
<key>Value</key>
<dict>
<key>string</key>
<string></string>
<key>attachmentsByRange</key>
<dict>
<key>{0, 1}</key>
<dict>
<key>Type</key>
<string>Variable</string>
<key>VariableName</key>
<string>label</string>
</dict>
</dict>
</dict>
</dict>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.choosefrommenu</string>
<key>UUID</key>
<string>00000000-0000-0000-0000-000000000013</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFControlFlowMode</key>
<integer>2</integer>
<key>GroupingIdentifier</key>
<string>00000000-0000-0000-0000-000000000002</string>
</dict>
</dict>
<dict>
<key>WFWorkflowActionIdentifier</key>
<string>is.workflow.actions.alert</string>
<key>UUID</key>
<string>00000000-0000-0000-0000-000000000014</string>
<key>WFWorkflowActionParameters</key>
<dict>
<key>WFAlertActionMessage</key>
<string>Timer started!</string>
</dict>
</dict>
</array>
</dict>
</plist>
Shortcuts preview coming soon
How it works
The menu presents three timer durations. Each case calls Scripting.wait(), which compiles to the "Wait" action, then sends a notification with Notification.showNotification().
The label variable is defined once and reused across all three cases as the notification title. In the compiled shortcut, this becomes a magic variable that each "Show Notification" action references.
Notification.showAlert runs after the selected case. In the compiled shortcut, it appears after the "End Menu" action.