NSPasteboard in System Extension

I am trying to access clipboard via NSPasteboard API from a System Extension. However, all of its get methods return empty arrays and nil objects. Is that expected? Is there some permission or entitlement required for a System Extension to access clipboard?

Answered by DTS Engineer in 833832022

This question indicates you’ve seriously misunderstood macOS’s layered architecture. Lemme try and set you straight.

An ES client must be a launchd daemon of some form [1]. As such, it operates within the global execution context. NSPasteboard is part of AppKit, which is one of our GUI frameworks. GUI frameworks only work reliably within a GUI login context. If you write code to call a GUI framework from the global execution context you will encounter weird problems.

Many of those problems are practical — things don’t work, or crash — but that’s not the main issue here. Rather, there’s a fundamental layering issue. A Mac always has a single global execution context but it can have many different GUI login contexts simultaneously, due to both fast user switching and screen sharing. Thus, it’s impossible for a daemon to access the user’s pasteboard because there’s no way to answer the question of “Which user’s pasteboard?”

I talk about this in great detail in the old, but still fairly accurate, TN2083 Daemons and Agents.

If you want to monitor the pasteboard you have to do that from code within each user’s GUI execution context. Folks usually do that sort of thing using a launchd agent that’s started from /Library/LaunchAgents, meaning that there’s a separate instance running within each GUI login context. This ‘daemon with a group of cooperating agents’ concept is something I discuss in more detail in TN2083.

The other thing you should consider doing is filing an enhancement request against Endpoint Security that asks for a specific API to achieve your high-level goal.

If you do file such an ER, please post your bug number, just for the record.

Share and Enjoy

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

[1] Either a launchd daemon itself or a system extension, which is more-or-less equivalent to launchd daemon.

This question indicates you’ve seriously misunderstood macOS’s layered architecture. Lemme try and set you straight.

An ES client must be a launchd daemon of some form [1]. As such, it operates within the global execution context. NSPasteboard is part of AppKit, which is one of our GUI frameworks. GUI frameworks only work reliably within a GUI login context. If you write code to call a GUI framework from the global execution context you will encounter weird problems.

Many of those problems are practical — things don’t work, or crash — but that’s not the main issue here. Rather, there’s a fundamental layering issue. A Mac always has a single global execution context but it can have many different GUI login contexts simultaneously, due to both fast user switching and screen sharing. Thus, it’s impossible for a daemon to access the user’s pasteboard because there’s no way to answer the question of “Which user’s pasteboard?”

I talk about this in great detail in the old, but still fairly accurate, TN2083 Daemons and Agents.

If you want to monitor the pasteboard you have to do that from code within each user’s GUI execution context. Folks usually do that sort of thing using a launchd agent that’s started from /Library/LaunchAgents, meaning that there’s a separate instance running within each GUI login context. This ‘daemon with a group of cooperating agents’ concept is something I discuss in more detail in TN2083.

The other thing you should consider doing is filing an enhancement request against Endpoint Security that asks for a specific API to achieve your high-level goal.

If you do file such an ER, please post your bug number, just for the record.

Share and Enjoy

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

[1] Either a launchd daemon itself or a system extension, which is more-or-less equivalent to launchd daemon.

Thanks for your reply.

Could this layering also be the reason I am unable to invoke any XPC services that are part of the app from ES Extension?

NSPasteboard in System Extension
 
 
Q