Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

How to learn most recent best practices?

Hello.

Background: Most learning resources are for leaning Swift/Objective-C. I'm pretty sure I need something different. I'm already an experienced software engineer, just new to iOS/MacOS development. My problem is not learning the language, but rather how to learn modern best practices. I cannot find examples for what I'm looking for. So much seems to be sparse on implementation details, out of date, or both.

I'm trying to write an app that has a few distinct parts. The UI portion will be mostly a menu bar app, which I am not having a problem discovering resources for how to implement. The app will also have a daemon and utilize network extensions. This is where I am having trouble.

  • What's the current best practices on how to write and launch a daemon?
  • Should the daemon be its own library/package which is them imported into the main app? If so, which Xcode template do I use for this? Are there any Hello World! examples of this?
  • What is the best way for a UI app to communicate with a daemon?
  • Are there any Hello World! repositories on how to implement network extensions? Should this be done in the main UI app, or in a separate library/package?

TIA

I'm already an experienced software engineer, just new to iOS/MacOS development

Those are two radically different environments. Most of your question seems to pertain to macOS. But you said you're new to the platform, and learning how to swim by diving into the deep end.

My problem is not learning the language, but rather how to learn modern best practices.

What do you mean by "modern best practices"? It would really be helpful if you provided some context.

Do you have a contract and funding to write this macOS network app? If so, then there do exist some older documentation and newer tips on Apple-approved ways to accomplish this task. But unless someone is already paying you a lot of money to do this, I wouldn't even call it a "good idea", let alone a "best practice."

What's the current best practices on how to write and launch a daemon?

You mentioned a network extension. It would be a better idea to start your search there. Network extensions are a relatively new artifact that is relatively well-understood, documented, and supported in modern versions of macOS. If you go looking for daemons, you're likely to get stuck in ideas from a decade ago, if not older. I'm not even sure you should be using a daemon at all.

Should the daemon be its own library/package which is them imported into the main app? If so, which Xcode template do I use for this? Are there any Hello World! examples of this?

This part is easy enough. Modern best practice is to bundle all of this inside the app bundle. You start with an app and then add a "network extension" target. The "best practice" would be to start with a WWDC video on modern network extensions. Note that "modern" is becoming a shorter and shorter timeframe. It's almost measured in months at this point.

What is the best way for a UI app to communicate with a daemon?

Again, forget daemons for now.

Are there any Hello World! repositories on how to implement network extensions? Should this be done in the main UI app, or in a separate library/package?

I strongly recommend starting with a WWDC video. I'm sure there are many. Network extensions are an absurdly popular thing these days. Then look at the documentation.

Thank you for your response.

Those are two radically different environments. Most of your question seems to pertain to macOS. But you said you're new to the platform, and learning how to swim by diving into the deep end.

Correct. I'm targetting MacOS. I Would target both, but the network extension I want to use aren't available in iOS unless it's on a managed device, which I'm not prepared to consider yet.

What do you mean by "modern best practices"? It would really be helpful if you provided some context.

For example, when researching daemons, it looks like their are multiple folder paths to put them in as well as multiple ways to launch them. How am I supposed to know which is considered best practice?

Do you have a contract and funding to write this macOS network app? If so, then there do exist some older documentation and newer tips on Apple-approved ways to accomplish this task. But unless someone is already paying you a lot of money to do this, I wouldn't even call it a "good idea", let alone a "best practice."

No contract. No funding. I'm writing this in what little spare time I can claw and scratch for myself.

You mentioned a network extension. It would be a better idea to start your search there. Network extensions are a relatively new artifact that is relatively well-understood, documented, and supported in modern versions of macOS. If you go looking for daemons, you're likely to get stuck in ideas from a decade ago, if not older. I'm not even sure you should be using a daemon at all.

It's my understanding that I have to use a daemon because A) I plan on using a privileged port, and B) I want it to be long running and available system wide regardless of user. Is there some other way to achieve this? I'm not married to the idea of a daemon.

This part is easy enough. Modern best practice is to bundle all of this inside the app bundle. You start with an app and then add a "network extension" target. The "best practice" would be to start with a WWDC video on modern network extensions. Note that "modern" is becoming a shorter and shorter timeframe. It's almost measured in months at this point.

Thanks.

I strongly recommend starting with a WWDC video. I'm sure there are many. Network extensions are an absurdly popular thing these days. Then look at the documentation.

Will do.

What's the current best practices on how to write and launch a daemon?

It depends on the user experience you’re looking for:

  • If you want to distribute a standalone app that puts the user in charge, SMAppService is the best option.

  • If your focus is on managed environments, an installer package is appreciated there.

There’s nothing to stop you doing both, that is, have the same core code that’s packaged differently for different audiences.

Also, on the Mac it’s possible to package an NE provider as a system extension. See TN3134 Network Extension provider deployment. Sysexes are pretty much equivalent to a launchd daemon, so it’s possible that you might be able to skip the daemon entirely.

Should the daemon be its own library/package which is them imported into the main app?

That question doesn’t make sense as written. A daemon is an executable, not a library.

In most cases it’s possible to create a framework (or dynamic library) that you share between your app and your daemon. Whether that makes sense depends on what sort of code you want to share.

Also, the mechanics of that can be tricky if one of the clients of your framework is your sysex. Lemme know if that’s the case and I’ll chase down my explanation of the problem and its solution.

What is the best way for a UI app to communicate with a daemon?

XPC. See XPC Resources for links to docs, forums posts, and so on.

Oh, and there’s a similar post for NE: Network Extension Resources.


the network extension I want to use aren't available in iOS unless it's on a managed device

What sort of provider specifically?

It's my understanding that I have to use a daemon because A) I plan on using a privileged port, and B) I want it to be long running and available system wide regardless of user.

You don’t need to write a daemon to listen on a low-numbered port. We dropped that restriction in macOS 10.14 [1].

Your second reason is a good one. Specifically, daemons run in the global context, so they run continuously. Other types of code come and go as users log in and out.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] In the standard cases. There are specific cases where it’s still applied.

For example, when researching daemons, it looks like their are multiple folder paths to put them in as well as multiple ways to launch them. How am I supposed to know which is considered best practice?

I was actually hoping to get more context regarding the app your are trying to build, other than "network extension". What is this app supposed to do?

As I said before, this is an advanced topic. The documentation is targeted to people building various kinds of low-level system modifications. That can be confusing if you don't need to do all of those things at once.

The current best practice is to bundle both the daemon and the launchd config files (as well as everything else) in specific subdirectories inside your app bundle. Apple changed the design in macOS Ventura. In the past, it was customary to scatter all these bits in various places.

You're specifically asking about "most recent best practices". Most of the advice you'll find on the internet is out-of-date and misleading.

Here is a link from the documentation.

No contract. No funding. I'm writing this in what little spare time I can claw and scratch for myself.

Best practices have changed over the years due to technical, social, and market considerations. Most people are actually seeking something more than simply writing code. The documentation and the APIs themselves are designed for people looking to distribute software to others.

How to learn most recent best practices?
 
 
Q