Hey!
I'm trying to create an XPC messaging feature between my daemon and main application.
I'm trying to use the new Swift low-level API available from macOS 14.0. The documentation is extremely confusing when looking at it from Swift:
The xpc_listener_t type
-
Seems to be something I shouldn't use in the Swift API, and would rather have to use
XPCListener
. -
Also, it appears to have no public API other than the
xpc_listener_set_peer_code_signing_requirement
function. Which would make it impossible to create this type. -
However, when going into
xpc.h
, one can see that there is an API in fact:API_AVAILABLE(macos(14.0), macCatalyst(17.0)) API_UNAVAILABLE(ios, tvos, watchos) XPC_EXPORT XPC_SWIFT_NOEXPORT XPC_RETURNS_RETAINED XPC_WARN_RESULT xpc_listener_t _Nullable xpc_listener_create(const char * service, dispatch_queue_t _Nullable target_queue, xpc_listener_create_flags_t flags, xpc_listener_incoming_session_handler_t incoming_session_handler, xpc_rich_error_t _Nullable * _Nullable error_out);
which is a very unusual declaration - the first parameter for example shows up as
Int8
type in Swift. Not to mention I haven't been able to create the next parameter,xpc_listener_create_flags_t
at all, even though it seems to be a UInt64-based flag based on the C declaration, but passing UInt64(0) throws a compiler error. It really seems like something I shouldn't use from Swift. -
But then again, the extremely important security-related API mentioned above,
xpc_listener_set_peer_code_signing_requirement
can only take anxpc_listener_t
object as a parameter, not anXPCListener
type. -
There seems to be no conversion available between the two. However the documentation in the XPC framework seems to be telling the story of these two types being very equal, because of the following:
The xpc_session_t type
- seemingly again has only deprecated methods mostly, the important one staying behind is
xpc_session_set_peer_code_signing_requirement
. - However, this would again require the creation of an
xpc_session_t
object, for which in the XPC framework one will find declarations like:
plus basically all API of@available(macOS, introduced: 13.0, deprecated: 14.0, renamed: "XPCSession") @available(macCatalyst, introduced: 16.0, deprecated: 17.0, renamed: "XPCSession") @available(iOS, unavailable) @available(tvOS, unavailable) @available(watchOS, unavailable) public typealias xpc_session_t = OS_xpc_object
XPCSession
being originally declared asxpc_session_*
APIs and all of them havingdeprecated: 14.0, renamed: *
marks. This is telling mexpc_session_t
andXPCSession
are in fact the same/same-ish. - But again, there is seemingly no conversion between these two types. Which brings me to again being unable to create a code signing requirement for the
XPCSession
object.
I've read some older forum posts, and I saw Apple Engineers admitting the code signing requirement APIs are missing from the new Swift APIs, however they seem to have been added in macOS 14.4 - although it appears to have been mistakenly added to the C-family functions, which have not been exposed to Swift correctly, because they still use the deprecated xpc_listener_t
and xpc_session_t
types.
So my question is: what is going on here? :) Making XPC connections without a code signing requirement in 2025 seems like a no-go, so do I have to still stick with C - even though this new API seems to be focused on Swift?
Lemme see if I have this straight:
- You want to use the new Swift XPC API for app-to-daemon XPC communication.
- You want the daemon to validate the code signature of the client.
Is that right?
If so, the source of your confusion is that currently shipping systems have no support for this. Fortunately, that seems to have changed in macOS 26 (currently in beta). See Validating Signature Of XPC Process.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"