Indeed, even the macos developer center has limited information
resources.
There are some useful docs but, sadly, they’re all in the documentation archive. Specifically:
The latter covers the concept of execution contexts in great detail, and that really matters to your project.
Can daemons be downloaded from the app store?
No. Specifically, this requirement:
I want to develop [a program] that runs after system boot without
login.
is not feasible in a Mac App Store app.
a Daemon; Is it a simple console application combined with a plist?
As always, it depends.
To start, “console application” doesn’t accurately describe a daemon. If someone says “console application” to me, I think of something that runs in Terminal but which is interactive. Think vi.
A better term is command-line tool, which encompasses application-y stuff (vi), traditional shell stuff (cat), and daemons and agents.
Xcode has a macOS > Command Line Tool template that may be the best starting point for you. I say may because it depends on whether your daemon ends up needing entitlements. If it does, it’s better to start with the macOS > App template, as discussed in Signing a Daemon with a Restricted Entitlement.
I am working on an api related to mirroring the screen to android
phone. Do you think a daemon has full access to wifi/ble and screen
capture APIs?
Definitely not. TN2083 describes the layered execution contexts of macOS. A daemon exists in the global context and it can only access daemon-safe things. Of the list you mentioned:
-
Only Wi-Fi is truly daemon safe [1].
-
On the screen capture front, such code must be running in a GUI login session.
-
For Bluetooth LE, the Core Bluetooth API was historically daemon safe but the recent introduction of System Preferences > Security & Privacy > Privacy > Bluetooth has muddied the waters considerably. As things currently stand, my advice is that you do your Bluetooth work in a GUI login session.
So, how can you make this work? Screen sharing products are usually based on two cooperating executables:
-
A launchd daemon, which is the product’s global presence. It coordinates shared state, including the networking.
-
A launchd agent, which is the daemon’s agent (hey hey) in each GUI login session. Configure that agent [2] to run in both the pre-login context (LoginWindow) and GUI per-user context (Aqua). It then connects to the daemon via IPC (typically XPC) to coordinate its work.
Keep in mind there may be 0 or more instances of your launchd agent, running in an arbitrary combination of pre-login and per-user contexts. That’s why you need the daemon, to act as a central hub for all that work.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] I presume you’re using Wi-Fi to mean “networking in general”. If you’re actually trying to work with low-level Wi-Fi APIs — and on macOS that means Core WLAN — the story gets more complex.
[2] Via the LimitLoadToSessionType property in the launchd property list; see the launchd.plist man page for details.