Introduction
SwiftDialog is a great tool to display a user interface for scripts. It can be used to request information from the user, or simply to display information in a nice and clean way.
One of the features of SwiftDialog is to display images in various places such as in the top-left corner of the window, in the main message area or in a list of items. And the way SwiftDialog does this is very clever since you can use a local image file, a URL pointing to an image, an application (in which case SwiftDialog retrieves its icon), an SF Symbol, or an emoji.
That last option is what this article is about.
The problem
The way SwiftDialog takes emojis is very simple, as stated in the documentation, you just pass the icon as a string of text. For example, the argument below would display a printer icon, such as the one seen in the capture above.
--icon text=🖨️
With a script in UTF-8, you can therefore simply call SwiftDialog with your emoji in the various arguments, wherever necessary, and get a very nice image to illustrated your process and make it more user-friendly.
Enters Jamf.
If you want your script to be executed by Jamf as part of a policy, you will have to add that script to your Jamf instance, usually by copy-pasting, or using the API.
When pasting your script in the Jamf Pro web interface, everything will look okay :
However, as soon as you click “Save”, you will see this :
The emoji has been replaced by the dreaded � character.
My understanding is that Jamf cannot store scripts in the UTF-8 format, and therefore does not support emojis.
The fix
There is a pretty simple fix for this, which involves using the Unicode code for each emoji. If you open a Terminal window and type
echo "\U0001F5A8"
You will get the printer emoji show above.
The fix is therefore to refer to each emoji by its code. I have written a small function for this :
emoji() {
local EMOJI_CODE="$1"
echo -e "\U000$EMOJI_CODE"
}
With this function, instead of calling SwiftDialog with the argument
--icon text=🖨️
I will call it with
--icon text="$(emoji 1F5A8)"
A list of all emojis with their code can be found here (plain text file) or here (prettier HTML page).
Since the emoji does not appear directly in the script, it will not be messed up by Jamf.
The catch
However, there is a catch !
In my case, I want SwiftDialog to run over the Login Window. My understanding is that in this special environment where no user is logged in, the locale settings do not exist. In that case, the default charset is ASCII and not UTF-8. That, in turn, prevents scripts from correctly using emojis.
Thankfully, the fix is easy. You only need to add two lines at the beginning of the script that will define the langage and the charset:
export LC_ALL="fr_CH.UTF-8"
export LC_CTYPE="fr_CH.UTF-8"
In my case, I set the langage to French (and more specifically Switzerland) with UTF-8 support. The first part is not really important for the sake of this article, and you will want to adapt it to your own langage. The second part however, is vital to making emojis work. A list of available UTF-8 locale can be obtained with the following command:
locale -a | grep UTF-8
Conclusion
With these two lines that set the charset and the simple emoji function, I now have a fully-functional script that makes for a very nice user interface to inform users of the progress of the computer’s configuration. All of it is made possible by SwiftDialog. The very first screen capture you can see in this article is the result of such a script and is running on the Login Window
I am now ready to upgrade my zero-touch, zero-user deployment workflow and move away from DEPNotify.