Observe NSDistributedNotification in launch daemon process

I have used

[[NSDistributedNotificationCenter defaultCenter] addObserver 

in process AA to listen notification from other process BB, It works fine. But when make the observer process AA as a launch daemon (which is started by launchd), It found below difference.

If run process BB as root privilege, AA can not receive notification posted by BB. If make process BB as a launch daemon, AA can receive notification posted by BB.

What was happened in above difference, It can not find any document about this, Thanks.

Accepted Reply

Distributed notifications are scoped to a specific execution context. Your daemon and your GUI code run in different contexts, and hence this problem.

For more background on execution contexts, see Technote 2083 Daemons and Agents. It’s super old, but the core concepts are still sound.

If run process BB as root privilege

You mean using sudo? If so, be aware that sudo only switches the BSD parts of the execution context. That leaves the process in a weird state, with a mixed execution context. It’s best to avoid that.

If you want truly global notifications, use Darwin notifications. You can access these through CFNotificationCenterGetDarwinNotifyCenter but, IMO, it’s actually easy to use the lower-level <notify.h> API. See the notify man page for details.

However, you need to be careful here. Remember that multiple GUI users can be logged in simultaneously, via fast user switching or screen sharing, and thus your notification approach has to allow for that possibility. And it’s not just correctness that’s a concern: You don’t want to ‘leak’ state between users.

If you can supply more details about what you’re doing, I should be able offer further guidance.

Share and Enjoy

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

Replies

Distributed notifications are scoped to a specific execution context. Your daemon and your GUI code run in different contexts, and hence this problem.

For more background on execution contexts, see Technote 2083 Daemons and Agents. It’s super old, but the core concepts are still sound.

If run process BB as root privilege

You mean using sudo? If so, be aware that sudo only switches the BSD parts of the execution context. That leaves the process in a weird state, with a mixed execution context. It’s best to avoid that.

If you want truly global notifications, use Darwin notifications. You can access these through CFNotificationCenterGetDarwinNotifyCenter but, IMO, it’s actually easy to use the lower-level <notify.h> API. See the notify man page for details.

However, you need to be careful here. Remember that multiple GUI users can be logged in simultaneously, via fast user switching or screen sharing, and thus your notification approach has to allow for that possibility. And it’s not just correctness that’s a concern: You don’t want to ‘leak’ state between users.

If you can supply more details about what you’re doing, I should be able offer further guidance.

Share and Enjoy

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

Thanks @eskimo

Yes, I use sudo to launch process BB for testing. From you provided execution context, I know it can not work. As My understanding, It should post notification between launch daemon and launch daemon, or GUI application and GUI application. except when it need post notification from daemon to GUI application, it need to use NSDistributedNotificationPostToAllSessions option.

it need to use NSDistributedNotificationPostToAllSessions option.

Oh, yeah, that’d do it. I completely forgot about that option!

Share and Enjoy

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