nano ~/Library/LaunchAgents/com.yourname.walkreminder.plist
<?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>Label</key>
<string>com.yourname.walkreminder</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
<string>osascript -e 'display notification "Time to take a walk" with title "Reminder" sound name "Ping"'; afplay /Users/yourusername/Sounds/Walk.mp3</string>
</array>
<key>StartCalendarInterval</key>
<array>
<dict>
<key>Hour</key>
<integer>14</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
</array>
<key>StandardOutPath</key>
<string>/tmp/walkreminder.log</string>
<key>StandardErrorPath</key>
<string>/tmp/walkreminder.err</string>
</dict>
</plist>
In the above, the schedule is to run once a day at 14:00 hours. For running every half an hour from the time the user was logged on, we can use
<key>StartInterval</key>
<integer>1800</integer>
instead of <key>StartCalendarInterval</key>
Or, in my case, since I wanted every half an hour aligned to 0:00 and 0:30 exactly,
<key>StartCalendarInterval</key>
<array>
<dict>
<key>Minute</key>
<integer>0</integer>
</dict>
<dict>
<key>Minute</key>
<integer>30</integer>
</dict>
</array>
We had to use a Sounds directory which we had created, since afplay could not access the Downloads directory when run from launchd.
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.yourname.walkreminder.plist
and test with
launchctl kickstart -k gui/$(id -u)/com.yourname.walkreminder
Troubleshooting can be done with
plutil -lint ~/Library/LaunchAgents/com.yourname.walkreminder.plist
launchctl list | grep walkreminder
cat /tmp/walkreminder.err