https://developer.apple.com/forums/thread/708877
XPC is the preferred inter-process communication (IPC) mechanism on Apple platforms. XPC has three APIs:
The high-level NSXPCConnection API, for Objective-C and Swift
The low-level Swift API, introduced with macOS 14
The low-level C API, which, while callable from all languages, works best with C-based languages
General:
Forums subtopic: App & System Services > Processes & Concurrency
Forums tag: XPC
Creating XPC services documentation
NSXPCConnection class documentation
Low-level API documentation
XPC has extensive man pages — For the low-level API, start with the xpc man page; this is the original source for the XPC C API documentation and still contains titbits that you can’t find elsewhere. Also read the xpcservice.plist man page, which documents the property list format used by XPC services.
Daemons and Services Programming Guide archived documentation
WWDC 2012 Session 241 Cocoa Interprocess Communication with XPC — This is no longer available from the Apple Developer website )-:
Technote 2083 Daemons and Agents — It hasn’t been updated in… well… decades, but it’s still remarkably relevant.
TN3113 Testing and Debugging XPC Code With an Anonymous Listener
XPC and App-to-App Communication forums post
Validating Signature Of XPC Process forums post
This forums post summarises the options for bidirectional communication
This forums post explains the meaning of privileged flag
Related tags include:
Inter-process communication, for other IPC mechanisms
Service Management, for installing and uninstalling Service Management login items, launchd agents, and launchd daemons
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
XPC
RSS for tagXPC is a a low-level (libSystem) interprocess communication mechanism that is based on serialized property lists.
Posts under XPC tag
72 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I have a custom object which gets passed back to the main app from XPC.
I whitelist it like so:
NSSet *expectedClass = [NSSet setWithObjects:[NSArray class],
[MyCustomClass class],
nil];
[interface setClasses:expectedClass forSelector:@selector(myMethodNameHere:withCompletion:)
argumentIndex:0
ofReply:YES];
Now my custom class conforms to NSSecureCoding. It does have an array property of another custom class.
@property (nonatomic,readonly) NSArray *arraypropertyOfOtherClass;
Which is decoded in -initWithCoder: using:
-decodeArrayOfObjectsOfClasses:forKey:
Now on macOS Tahoe this is all walking fine. But I just tested on macOS Monterey and I get the following error:
Exception: decodeObjectForKey: too many nested collections when explicitly decoding a single collection.
How should I handle this for earlier versions of macOS?
Hello,
I'm running into an issue with a complex macOS application (non-AppStore) structure involving an unsandboxed system daemon and a sandboxed SSO Extension attempting to communicate via XPC Mach service.
The macOS app is composed of three main components:
Main App: unsandboxed, standard macOS application.
System Daemon: unsandboxed executable installed with a .plist to /Library/LaunchDaemons/ and loaded by launchd. It exposes an XPC Mach Service.
SSO Extension: a sandboxed Authentication Services Extension (ASAuthorizationProviderExtension).
Main App to System Daemon communication works perfectly. The unsandboxed main app can successfully create and use an XPC connection to the System Daemon's Mach service.
But SSO Extension cannot establish an XPC connection to the System Daemon's Mach service, despite using the recommended temporary exception entitlement. I have added the following entitlement to the SSO Extension's entitlements file:
<key>com.apple.security.temporary-exception.mach-lookup.global-name</key>
<array>
<string>my.xpc.service.system.daemon</string>
</array>
(The name my.xpc.service.system.daemon is the exact name registered by the System Daemon in its Launch Daemon plist's MachServices dictionary.)
When the SSO Extension attempts to create the connection, the following log output is generated:
default 08:11:58.531567-0700 SSOExtension [0x13f19b090] activating connection: mach=true listener=false peer=false name=my.xpc.service.system.daemon
default 08:11:58.532150-0700 smd [0xb100d8140] activating connection: mach=false listener=false peer=true name=com.apple.xpc.smd.peer[1575].0xb100d8140
error 08:11:58.532613-0700 smd Item real path failed. Maybe the item has been deleted?
error 08:11:58.532711-0700 SSOExtension Unable to find service status () error: 22
The error Unable to find service status () error: 22. Error code 22 typically translates to EINVAL (Invalid argument), but in this context, it seems related to the system's ability to find and activate the service for the sandboxed process.
Questions:
Is the com.apple.security.temporary-exception.mach-lookup.global-name entitlement sufficient for a sandboxed SSO Extension to look up a system-wide Launch Daemon Mach service, or are there additional restrictions or required entitlements for extensions?
The smd log output Item real path failed. Maybe the item has been deleted? seems concerning. Since the unsandboxed main app can connect, this suggests the service is running and registered. Could this error indicate a sandbox permission issue preventing smd from verifying the path for the sandboxed process?
Are there specific sandboxing requirements for Mach service names when communicating from an Extension versus a main application?
Any guidance on how a sandboxed SSO Extension can reliably connect to an unsandboxed, non-app-group-related system daemon via XPC Mach service would be greatly appreciated!
We have an application that sets a code signing requirement on a XPC connection between a File Provider extension and the main application. Only with a specific Developer ID certificate <DEVELOPER_ID_TEAM_IDENTIFIER> that designated requirement is not accepted and the application crashes with EXC_CRASH (SIGABRT) and the stacktrace
Thread 1 Crashed:: Dispatch queue: com.apple.root.default-qos
0 libsystem_kernel.dylib 0x19b556388 __pthread_kill + 8
1 libsystem_pthread.dylib 0x19b58f88c pthread_kill + 296
2 libsystem_c.dylib 0x19b498a3c abort + 124
3 libc++abi.dylib 0x19b545384 abort_message + 132
4 libc++abi.dylib 0x19b533cf4 demangling_terminate_handler() + 344
5 libobjc.A.dylib 0x19b1b8dd4 _objc_terminate() + 156
6 libc++abi.dylib 0x19b544698 std::__terminate(void (*)()) + 16
7 libc++abi.dylib 0x19b547c30 __cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*) + 88
8 libc++abi.dylib 0x19b547bd8 __cxa_throw + 92
9 libobjc.A.dylib 0x19b1aecf8 objc_exception_throw + 448
10 Foundation 0x19d5c3840 -[NSXPCConnection setCodeSigningRequirement:] + 140
11 libxpcfileprovider.dylib 0x301023048 NSXPCConnection.setCodeSigningRequirementFromTeamIdentifier(_:) + 1796
12 libxpcfileprovider.dylib 0x30101dc94 closure #1 in CallbackFileProviderManager.getFileProviderConnection(_:service:completionHandler:interruptionHandler:exportedObject:) + 1936
13 libxpcfileprovider.dylib 0x30101e110 thunk for @escaping @callee_guaranteed @Sendable (@guaranteed NSXPCConnection?, @guaranteed Error?) -> () + 80
14 Foundation 0x19d46c3a4 __72-[NSFileProviderService getFileProviderConnectionWithCompletionHandler:]_block_invoke_2.687 + 284
15 libdispatch.dylib 0x19b3d7b2c _dispatch_call_block_and_release + 32
16 libdispatch.dylib 0x19b3f185c _dispatch_client_callout + 16
17 libdispatch.dylib 0x19b40e490 + 32
18 libdispatch.dylib 0x19b3e9fa4 _dispatch_root_queue_drain + 736
19 libdispatch.dylib 0x19b3ea5d4 _dispatch_worker_thread2 + 156
20 libsystem_pthread.dylib 0x19b58be28 _pthread_wqthread + 232
21 libsystem_pthread.dylib 0x19b58ab74 start_wqthread + 8
The designated codesign requirement on the XPC connection is set to
anchor apple generic and certificate leaf[subject.OU] = <DEVELOPER_ID_TEAM_IDENTIFIER>"
We have verified the designated code sign requirement to be valid on both the main bundle and the embedded extension using:
codesign --verify -v -R '=anchor apple generic and certificate leaf[subject.OU] = "<DEVELOPER_ID_TEAM_IDENTIFIER>"' *.app
codesign --verify -v -R '=anchor apple generic and certificate leaf[subject.OU] = "<DEVELOPER_ID_TEAM_IDENTIFIER>"' *.app/Contents/PlugIns/*
I'm working on a Mac app that receives a process ID via NSXPCConnection, and I'm trying to figure out the best way to determine whether that process is a native macOS app like Safari—with bundles and all—or just a script launched by something like Node or Python. The executable is signed with a Team ID using codesign.
I was thinking about getting the executable's path as one way to handle it, but I’m wondering if there’s a more reliable method than relying on the folder structure.
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
XPC
Inter-process communication
I’m using a custom Installer plug-in (InstallerPane) to collect sensitive user input (username/password) during install. After the payload is laid down, I need to send those values to a newly installed agent (LaunchAgent) to persist them.
What I tried
I expose an XPC Mach service from the agent and have the plug-in call it.
On the agent side I validate the XPC client using the audit token → SecCodeCopyGuestWithAttributes → SecCodeCheckValidity.
However, the client process is InstallerRemotePluginService-* (Apple’s view service that hosts all plug-ins), so the signature I see is Apple’s, not mine. I can’t distinguish which plug-in made the call.
Any suggestion on better approach ?
I am trying to send an anonymous XPC listener endpoint to my daemon from user context in order to be able to do some bidirectional XPC.
I was trying to use the new XPCListener and XPCSession objects and the easiest method I figured was using the Codable version of the send() methods, in which I wanted to send the XPCEndpoint object - alongside the name of the anonymous endpoint (because I want to have more XPCEndpoints sent over, so I want to be able to identify them.
However, trying to manually encode XPCEndpoint throws an exception:
ERROR: Missing CodingUserInfoKey CodingUserInfoKey(rawValue: "_XPCCodable")
Here is a simple command-line tool reproducing the issue:
import Foundation
import XPC
let listener = try XPCListener(service: "mach-service.xxx.yyy", incomingSessionHandler: {
$0.accept(incomingMessageHandler: { (msg: XPCReceivedMessage) in
return nil
})
})
var endpoint = listener.endpoint
do {
let endpointData = try JSONEncoder().encode(endpoint)
print("EndpointData object: \(endpointData.count) bytes")
} catch let error {
print("ERROR: \(error)")
}
Wrapping my object into an XPCDictionary, then adding multiple keys alongside an "endpoint" key with the XPCEndpoint as value works, but XPCDictionaries are less ideal - they don't even support vanilla Data objects, only ones converted to an xpc_object_t with xpc_data_* functions
Is this expected behavior? I shouldn't encode an XPCEndpoint myself? I am using the latest Xcode 26.0 beta, with deployment target of macOS 15.1, running on macOS 15.5.
(Btw it's also incorrect that this XPCEndpoint API is available from macOS 15.0 - it cannot be found in Xcode 15.4 under macOS 15.5. At the very best it's backDeployed but this isn't mentioned in its public declaration.)
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 an xpc_listener_t object as a parameter, not an XPCListener 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:
@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
plus basically all API of XPCSession being originally declared as xpc_session_* APIs and all of them having deprecated: 14.0, renamed: * marks. This is telling me xpc_session_t and XPCSession 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?
To validate incoming XPC connections from other executables, we perform SecCode checks for the dynamic signature of the connection (kSecCSDynamicInformation).
Reading the setCodeSigningRequirement(_:) function documentation it appears to perform only static signing checks, is that so?
If we use setCodeSigningRequirement(:) function in our listener(:, shouldAcceptNewConnection:) do we still need to check the dynamic information to be properly secure?
I have a project that leverages XPC and has interoperability between Swift and Objective-C++. I am presently getting a compile-time error in one of our unit test targets, of "Argument passed to call that takes no arguments" on the following code:
let interface = NSXPCInterface(with: XPCServiceDelegate.self)
My XPCServiceDelegate protocol is defined as:
@objc(XPCServiceDelegate) public protocol XPCServiceDelegate {
//...
}
For the longest time, this code has compiled successfully, and it has not recently changed. There are two confusing things about this error. The first is that I have a different build scheme that will compile correctly other code with the same structure. The other is that I have team members that are able to compile my failing scheme successfully on the same XCode version, OSVersion, and branch of our repository.
I've attempted numerous things to try to get this code to compile, but I've run out of ideas.
Here's what I've tried:
Clean build both on XCode 16.4 and XCode 26 Beta
Delete DerivedData and rebuild on XCode 16.4 and XCode 26 Beta
Delete and re-clone our git repository
Uninstall and reinstall XCode
Attempt to locate cached data for XCode and clear it out. (I'm not sure if I got everything that exists on the system for this.)
Ensure all OS and XCode updates have been applied.
The interface specification for NSXPCInterface clearly has an initializer with one arguement for the delegate protocol, so I don't know why the compiler would fail for this. Is there some kind of forward declaration or shadowing of NSXPCInterface? Do you have any ideas on what I could try next?
To gain exclusive access to keyboard HID devices like Amazon Fire Bluetooth remote controls, my app has been installing a privileged helper tool with SMJobBless in the past. The app - which also has Accessibility permissions - then invoked and communicated with that helper tool through XPC.
Now I'm looking into replacing that with a daemon installed through the newer SMAppService APIs, but running into a permission problem:
If I try to exclusively open a keyboard HID device from the SMAppService-registered XPC service/daemon (which runs as root as seen in Activity Monitor), IOHIDDeviceOpen returns kIOReturnNotPermitted.
I've spent many hours now trying to get it to work, but so far didn't find a solution.
Could it be that XPC services registered as a daemon through SMAppService do not inherit the TCC permissions from the invoking process (here: Accessibility permissions) - and the exclusive IOHIDDeviceOpen therefore fails?
I've discovered that a system network extension can communicate with a LaunchDaemon (loaded using SMAppService) over XPC, provided that the XPC service name begins with the team ID.
If I move the launchd daemon plist to Contents/Library/LaunchAgents and swap the SMAppService.daemon calls to SMAppService.agent calls, and remove the .privileged option to NSXPCConnection, the system extension receives "Couldn't communicate with a helper application" as an error when trying to reach the LaunchAgent advertised service. Is this limitation by design?
I imagine it is, but wanted to check before I spent any more time on it.
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
Service Management
XPC
System Extensions
Network Extension
I am trying to create an app bundle with an xpc service. The main app creates a keychain item, and attempts to share (keychain access groups) with the xpc service it includes in its bundle. However, the xpc service always encounters a 'user interaction not allowed' error regardless of how I create the keychain item. kSecAttrAccessiblei is set to kSecAttrAccessibleWhenUnlockedThisDeviceOnly, the keychain access group is set for both the main app and the xpc service and in the provisioning profile. I've tried signing and notarizing.
Is it ever possible for an xpc service to access the keychain? This all on macos 15.5.
I am building a tool that enables the user to write, auto-compile and interact with SwiftUI code (think something like a mini Xcode Canvas). Which so far works really well.
The app is not sandboxed since it uses tools like swiftc and sourcekit-lsp.
The obvious problem here is that since the 'Preview' part of the app is driven by arbitrary code a crash/hang there would lead to a termination of the whole app.
I understand that there are some private apis like NSRemoteView or CALayerHost but I would like to avoid them if I can.
From what I see reading other similar solutions IOSurface sharing + event forwarding might be the best solution.
So my question is: Is there a proper or recommended way to achieve this? Meaning having a fully interactive SwiftUI view presented in my host app but running on a separate process?
Any pointers to the right direction or examples or whatever could help me with this would be greatly appreciated.
An XPC service’s process has a system-managed lifecycle: the process is launched on-demand when another process tries to connect to it, and the system can decide to kill it when system resources are low. XPC services can tell the system when they shouldn’t be killed using xpc_transaction_begin/end.
Do extensions created with ExtensionFoundation and/or ExtensionKit have the same behavior?
Hello, I am having some issues with running an XPC server on an endpoint security and connecting to it from the sandboxed host application.
I tried doing the following:
setting xpc server in endpoint security extension entitlements:
<key>com.apple.developer.endpoint-security.client</key>
<true/>
<key>com.apple.security.xpc.server</key>
<true/>
Adding the mach service with the plist:
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.system-extension-endpoint-security</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).ESFExtension</string>
</dict>
<key>NSEndpointSecurityMachServiceName</key>
<string>[TEAMID]com.[UNIQUE_ID]</string>
</dict>
</plist>
Putting a mach-lookup in sandboxed host application entitlements
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.developer.system-extension.install</key>
<true/>
<key>com.apple.security.exception.mach-lookup.global-name</key>
<array>
<string>[TEAMID]com.[UNIQUE_ID]</string>
</array>
</dict>
Creating the server in the system extension using xpc_connection_create_mach_service(_service_name.c_str(), dispatch_get_main_queue(), XPC_CONNECTION_MACH_SERVICE_LISTENER);
with _service_name being the same as in the mach-lookup entitlement.
And connecting to it in the host app with:
xpc_connection_create_mach_service([self.serviceName UTF8String], dispatch_get_main_queue(), 0);
My problem is I get an xpc error 159 (sandbox restriction) in the lookup
(libxpc.dylib) [com.apple.xpc:connection] [0x600001a7db30] failed to do a bootstrap look-up: xpc_error=[159: Unknown error: 159]
I tried putting the sysex and the host app in the same app group, and it didn't help and I also read this is bad practice to have an app group between a sandboxed app and a system extension so I removed it.
I tried adding a temporary-exception and with it, the code works properly.
I tried with the XPC_CONNECTION_MACH_SERVICE_PRIVILEGED flag but it still didn't work.
Is it possible to have an XPC connection between a ES sysex and it's host app? Should the service name have a prefix of the bundle name or does it must have a certain pattern? Do I need to add some capability in the Certificates, Identifiers & Profiles?
Thanks for helping.
It looks like ExtensionKit (and ExtensionFoundation) is fully available on iOS 26 but there is no mention about this in WWDC.
From my testing, it seems as of beta 1, ExtensionKit allows the app from one dev team to launch extension provided by another dev team. Before we start building on this, can someone from Apple help confirm this is the intentional behavior and not just beta 1 thing?
I am developing a background application that acts as a metadata server under MacOS written in Swift. Sandboxed clients prompt the user to select URLs which are passed to the server as security scoped bookmarks via an App Group and the metadata will be passed back. I don't want the I/O overhead of passing the complete image file data to the server. All the variations I have tried of creating security scoped bookmarks in the client and reading them from the server fail with error messages such as "The file couldn’t be opened because it isn’t in the correct format." Can anyone guide me in the right direction or is this just not possible?
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
Files and Storage
App Sandbox
XPC
Hi,
I have a sandboxed app with a bundled sandboxed XPC service. When it’s launched, the XPC service registers a repeating XPC activity with the system. The activity’s handler block does get called regularly like I’d expect, but it stops being called once the main app terminates.
What’s the recommended way to fix this issue? Could I have a bundled XPC service double as a launch agent, or would that cause other problems?
I have an outside Mac App Store app. It has an action extension. I can't get it to run from Xcode. I try to debug it from Safari. It shows up in the menu when I click the 'rollover' button but it doesn't show up in the UI at all. Xcode doesn't give me any indication as to what the problem is. I see this logs out in console when I try to open the action extension:
Prompting policy for hardened runtime; service: kTCCServiceAppleEvents requires entitlement com.apple.security.automation.apple-events but it is missing for accessing={TCCDProcess: identifier=BundleIdForActionExtHere, pid=6650, auid=501, euid=501, binary_path=/Applications/AppNamehere.app/Contents/PlugIns/ActionExtension.appex/Contents/MacOS/ActionExtension}, requesting={TCCDProcess: identifier=com.apple.appleeventsd, pid=550, auid=55, euid=55, binary_path=/System/Library/CoreServices/appleeventsd},
I don't see why the Action extension needs Apple events but I added it to the entitlements anyway but it doesn't seem to matter. The action extension fails to open.
I have an accessory with MFi authenticaiton passed(got 0xAA05) and identification accepted (got 0x1D02). But when I try to open the target stream by using iAP2 EA session framework, I always enounter the same error looking like:
XPC connection error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.accessories.externalaccessory-server was invalidated from this process." UserInfo={NSDebugDescription=The connection to service named com.apple.accessories.externalaccessory-server was invalidated from this process.}
anybody can tell me what it related with? And what can I do to go through it quickly? Thank you much in advance.