After facing issues with Big Sur on an M1 Mac, the following approach was implemented via
launchctl
and osascript
to ensure an app is restarted if found to not be running.
This particular app was running stable on Catalina, and this approach is a temporary workaround until the root cause can be addressed. YMMV.
Create an applescript that executes your Mac application.
In this case, the application shows a window on startup, so there are additional lines to hide the window after 200ms. The application that is crashing in this example is Barrier keyboard and mouse sharing.
Replace references to barrier
with the application that is unstable in your case.
~/Users/YOURUSER/bin/barrier-keepalive.applescript
:
tell application "Barrier" to activate
delay 0.1
tell application "Finder" to set visible of process "Barrier" to false
This could easily be replaced with bash script, and the LaunchAgent
below modified
to call /bin/bash
rather than osascript
.
Leverage the launchd system to setup an interval-based service execution. Again, replace
barrier
with the necessary values to identify your application. The Label
can be a
dummy value that makes sense to you.
Update the StartInterval
to your desired value, in minutes.
~/Library/LaunchAgents/barrier.keepalive.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.barrierapp</string>
<key>ProgramArguments</key>
<array>
<string>osascript</string>
<string>/Users/YOURUSER/bin/barrier-keepalive/barrier-keepalive.applescript</string>
</array>
<key>StartInterval</key>
<integer>5</integer>
</dict>
</plist>
Once the above script and LaunchAgent
are in place, activate the agent in your console:
$ launchctl load ~/Library/LaunchAgents/barrier.keepalive.plist
Validate that the agent started successfully:
$ launchctl list | grep barrier
46215 0 application.barrier.812684.812809
- 0 com.barrierapp
You should see a 0
for the exit code on com.barrierapp
. This indicates successful
execution. Should you see another error code, get more details with
launchctl error <your code>
.
For example:
launchctl error 78
78: Function not implemented
Once the agent has been updated to address errors, reload it since the agents could be cached:
$ launchctl unload ~/Library/LaunchAgents/barrier.keepalive.plist
$ launchctl load ~/Library/LaunchAgents/barrier.keepalive.plist