XPC is a a low-level (libSystem) interprocess communication mechanism that is based on serialized property lists.

Posts under XPC tag

44 Posts

Post

Replies

Boosts

Views

Activity

Securely passing credentials from Installer plug-in to newly installed agent — how to authenticate the caller?
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 ?
5
0
1.7k
Oct ’25
Mac: Best way to distinguish native app process and script process spawned from executable (e.g. python node) through process_id
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.
1
0
300
Sep ’25
XPC codesign requirement crashes application
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/*
2
0
439
Sep ’25
SSO Extension Fails XPC Connection to System Daemon (mach-lookup exception used)
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!
2
0
335
Oct ’25
XPC: too many nested collections when explicitly decoding a single collection on macOS 12.7 (not on macOS Tahoe)
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?
2
0
352
Oct ’25
XPC Service Installed Outside App Doesn't Set Responsible
On macOS 15.7.1 I'm trying to install an XPC service outside the app (Developer ID). It mostly seems to go ok, but when I set Launch Constraints on Responsible, AMFI complains of a violation, saying the service is responsible for itself, and fails to launch. Removing that constraint (or adding the service itself to the constraint) works fine. The service is an optional download, and installed to /Users/Shared with a LaunchAgent specifying the MachService. The service is correctly launched and seems to pass all codesigning, notarization, and other checks, but the Responsible isn't set to the "calling" app. Is this broken, or working as intended?
3
0
796
Nov ’25
Hosting x86 Audio Units on Silicon Mac
My app encountered problems when trying to open an x86 audioUnit v2 on a Silicon Mac (although Rosetta is installed). There seems to be a XPC connection issue with the AUHostingService that I don't know how to fix. I observed other host apps opening the same plugins without problem, so there is probably something wrong or incompatible in my codes. I noticed that: The issue occurs whether or not the app is sandboxed. The issue does no longer occur when the app itself runs under Rosetta. There is no error reported by CoreAudio during allocation and initialization of the audio unit. The first notified errors appears when the unit calls AudioUnitRender from the rendering callback. With most x86 plugins, the error is on first call: kAudioUnitErr_RenderTimeout and on any subsequent call: kAudioComponentErr_InstanceInvalidated On the UI side, when the Cocoa View is loaded, it appears shortly, then disappears immediately leaving its superview empty. With another x86 plugin, the Cocoa View is loaded normally, but CoreAudio still emits kAudioUnitErr_NoConnection from AudioUnitRender, whether the view has been loaded or not, and the plugin produces no sound. I also find these messages in the console (printed in that order): CLIENT ERROR: RemoteAUv2ViewController does not override - and thus cannot react to catastrophic errors beyond logging them AUAudioUnit_XPC.mm:641 Crashed AU possible component description: aumu/Helm/Tyte My app uses the AUv2 API and I suspect that working with the AUv3 API would spare me these problems. However, considering how my audio system is built (audio units are wrapped into C++ classes and most connections between units are managed on the fly from the rendering callback), it would be a lot of work to convert, and I’m even not sure that all I do with the AUv2 API would be possible with the AUv3 API. I could possibly find an intermediate solution, but in the immediate future I'm looking for the simplest and fastest possible fix. If I cannot find better, I see two fallback options: In this part of the doc: “Beginning with macOS 11, the system loads audio units into a separate process that depends on the architecture or host preference”, does “host preference” means that it would be possible to disable the “out of process” behavior, for example from the app entitlements or info.plist? Otherwise, as a last resort, I could completely disable the use of x86 audioUnits when my app runs under ARM64, for at least making things cleaner. But the Audio Component API doesn’t give any info about the plugin architecture, how could I found it? Any tip or idea about this issue will be much appreciated. Thanks in advance!
2
0
1.3k
Nov ’25
Submitting an App using Chromium Embedded Framework (CEF) to the Mac App Store
Hi, We have several Apps that use CEF internally for real-time offscreen HTML rendering. Specifically, we have a framework with an embedded XPC service that itself uses CEF to render HTML and sends the resulting IOSurface back to the host App via XPC for rendering in a Metal pipeline. So far our Apps have only been available as a direct download, but recently we have been trying to submit one of them to the MAS and have run into several issues, CEF being one of them. The core of the issue seems to be that submission to the MAS requires that all executables, including XPC services, be signed with the sandbox entitlement. After enabling the sandbox on the host App, my XPC service with CEF continued to function as before. However, after signing the XPC service with the sandbox entitlement, it stopped working. After some research, it seems that the issue here is that the XPC service once signed with the entitlement is running in its own sandbox, and because CEF uses global Mach ports for internal communication, this then fails. Further, I have read from other developers that even if these issues are overcome by e.g. modifying CEF, they have been rejected by the review team because CEF uses some private API calls. So my question is, does anyone have concrete information on whether or not it will be possible to successfully submit an App using CEF in this way (App > Framework > XPC > CEF) for publication on the MAS? Further, as an alternative I have been looking at WebKit, specifically WKWebView and calling "takeSnapshot", as this seems to be the only documented way to retrieve pixels. However, it seems that this method is not designed for real-time rendering. Assuming that CEF is a non-starter for the MAS, is there anything specific that Apple recommends for real-time offscreen HTML rendering? Cheers, Dave Lincoln
0
0
450
Nov ’25
How can I create a more complex XPCPeerRequirement?
I have been updating some NSXPCConnection code in my macOS 26 app (not sandboxed) to use XPCSession and friends instead. And it is working well and the experience has been generally good. But I have run into a problem when using XPCSession.setPeerRequirement() which I really want to use. It works well when I use something simple like XPCPeerRequirement.isFromSameTeam() but I want to check some more requirements and also use the code from multiple apps (but same team). That is, I want to check for multiple identifiers and team ID and version (and perhaps also in the future that the certificate is a Developer ID). And previously I would use SecRequirementCreateWithString with an entitlement string conceptually like this: var entitlement = "anchor apple generic and (" entitlement += "identifier idA" entitlement += " or identifier idB" entitlement += ")" entitlement += " and certificate leaf[subject.OU] = TeamID" entitlement += #" and info [CFBundleShortVersionString] >= "1.0""# and it works just as it should when creating and using that SecRequirement so I don't think that there is anything particularly wrong with the entitlement. And I had hoped that I could use the same string with XPCPeerRequirement.hasEntitlement(entitlement) but it doesn't work (I get a general "Peer forbidden" error). So I think that I don't really understand what sort of entitlement that hasEntitlement() wants. And also I don't really understand the other ways available to create a XPCPeerRequirement. I have also tried to use a XPCDictionary with XPCPeerRequirement(lightweightCodeRequirements:) but I can't get that to work either (and it seems a bit wrong to have to drop down to use e.g. xpc_object_t with new modern API:s). So my question is: is it possible to create a XPCPeerRequirement with an entitlement like above and, in that case, how? Or is there some other work-around to use XPCSession.setPeerRequirement() with a more complex requirement, e.g. is there a way to combine multiple XPCPeerRequirements into one? Thank you for reading this. /Peter
1
0
525
Feb ’26
Issue with XPC communication between Network Extension and host application
Hello, I need to develop a Network Extension (Transparent Proxy) that sends data to the host application for analysis. Network Extension - XPC client Host application - XPC service I am trying to implement it with XPC. However, when attempting to connect, I see the following error in the system logs on client side. [0x1015a2050] failed to do a bootstrap look-up: xpc_error=[3: No such process] I assume the problem occurs because the Network Extension cannot find the registered XPC service. On the service side, I see the following message in the logs: 2026-02-24 13:15:36.419345+0300 localhost fgstnehost[58884]: (libxpc.dylib) [com.apple.xpc:connection] [0x100bdee70] activating connection: mach=true listener=true peer=false name=TEAM_ID.group.app_id.netfilter.xpc Entitlements Network Extension: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.developer.networking.networkextension</key> <array> <string>app-proxy-provider-systemextension</string> </array> <key>com.apple.security.application-groups</key> <array> <string>TEAM_ID.group.app_id.netfilter</string> </array> <key>com.apple.security.app-sandbox</key> <true/> <key>com.apple.security.xpc.mach-lookup.global-name</key> <array> <string>TEAM_ID.group.app_id.netfilter.xpc</string> </array> </dict> </plist> Entitlements host application: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.developer.networking.networkextension</key> <array> <string>app-proxy-provider-systemextension</string> </array> <key>com.apple.developer.system-extension.install</key> <true/> <key>com.apple.security.application-groups</key> <array> <string>TEAM_ID.group.app_id.netfilter</string> </array> <key>com.apple.security.app-sandbox</key> <true/> <key>com.apple.security.xpc.mach-service.name</key> <array> <string>TEAM_ID.group.app_id.netfilter.xpc</string> </array> </dict> </plist> Server.m @interface XPCServer () @property (nonatomic, strong) NSXPCListener *listener; @end @implementation XPCServer - (instancetype) init { self = [super init]; if (self != nil) { _listener = [[NSXPCListener alloc] initWithMachServiceName: XPC_SERVICE_ID]; _listener.delegate = self; } return self; } - (void) start { [self.listener resume]; } - (BOOL) listener:(NSXPCListener *) listener shouldAcceptNewConnection:(NSXPCConnection *) newConnection { return YES; } @end Client.m @interface XPCClient () @property (nonatomic, strong) NSXPCConnection *connection; @end @implementation XPCClient - (void) connect { self.connection = [[NSXPCConnection alloc] initWithMachServiceName: XPC_SERVICE_ID options: NSXPCConnectionPrivileged]; self.connection.invalidationHandler = ^{ [[OSLogger sharedInstance] error: "XPCClient: connection can not be formed or the connection has terminated and may not be re-established"]; }; self.connection.interruptionHandler = ^{ [[OSLogger sharedInstance] error: "XPCClient: the remote process exits or crashes"]; }; [self.connection resume]; } @end What could be the root cause of this issue? Are there any recommendations for implementing IPC between a Network Extension and aß Host Application? Thank you in advance.
2
0
390
Feb ’26
Trouble creating an XPC service for out-of-process rendering
I'm working on an editor for Bevy games and wanted the following workflow: Launch the game process Host a Metal view for the game's render target Use an XPC service to transfer an MTLSharedTextureHandle Keep the connection for editor/game communication and hot reload As such I created the following editor service: public let XPCEditorServiceName = "org.bevy.editor" public enum XPCEditorMessage: Codable { case ping } public enum XPCEditorReply: Codable { case pong } extension XPCListener { static let bevy = try! XPCListener(service: XPCEditorServiceName) { request in request.accept(XPCEditorService.init) } } struct XPCEditorService: XPCPeerHandler { let session: XPCSession private func handle(_ message: XPCEditorMessage) -> XPCEditorReply? { switch message { case .ping: return .pong } } func handleIncomingRequest(_ message: XPCReceivedMessage) -> (any Encodable)? { do { return handle(try message.decode()) } catch { return nil } } func handleCancellation(error: XPCRichError) { print(error) } } and I initialize it in my app's App initializer: // Launch the XPC service print(XPCListener.bevy) I wanted to test this using an executable target with the following main.swift: let session = try XPCSession(xpcService: XPCEditorServiceName) let response: XPCEditorReply = try session.sendSync(XPCEditorMessage.ping) print("Connected to editor!") The editor prints Listener<org.bevy.editor>(Active) but the game fails with Underlying connection was invalidated. Reason: Connection init failed at lookup with error 3 - No such process What am I doing wrong? PS. Would also appreciate an example of sending & rendering the MTLSharedTextureHandle both in editor & game.
2
0
233
Feb ’26
Current wisdom on multiple XPC services in a System Extension?
I'm following up on a couple of forum threads from 2020 to get more clarity on the current guidance for supporting multiple XPC services in system extensions. For context, I'm trying to create a system extension that contains both an Endpoint Security client and a Network Extension filter, and I'm seeing indications that the system may not expect this and doesn't handle it smoothly. First: Previous guidance indicated that the system would automatically provide a Mach service named <TeamID>.<BundleID>.xpc to use for communicating with the system extension. However, the SystemExtension man page currently documents an Info.plist key called NSEndpointSecurityMachServiceName and suggests that the default service name is deprecated; and in fact if this key is not set, I find a message in the Console: The extension from () is using the deprecated default mach service name. Please update the extension to set the NSEndpointSecurityMachServiceName key in the Info.plist file. I have accordingly set this key, but I wanted to confirm that this is the current best practice. Second, and more interesting: Another user was trying to do something similar and observed that the Mach service for the endpoint security client wasn't available but the NE filter was. Quinn did some research and replied that this was intended behavior, quoting the EndpointSecurity man page: "If ES extension is combined with a Network Extension, set the NEMachServiceName key in the Info.plist" (which I have also done), and concluding from this: ... if you have a combined ES and NE system extension then the Mach service provided by the NE side takes precedence. However, the current man page does not include this quoted text and says nothing about a combined ES and NE system extension. So I'm wondering about current best practice. If I do combine the ES and NE clients in a single system extension, should they each declare the Mach service name under their respective Info.plist keys? And could there be a single XPC listener for both, using the same service name under each key, or would it be better to have separate XPC listeners? Alternatively, would it be preferable to have each component in a separate system extension? (This would entail some rearchitecting of the current design.)
4
0
500
Mar ’26
Securing XPC Daemon Communication from Authorization Plugin
I'm working on securing communication between an Authorization Plugin and an XPC daemon, and I’d appreciate some guidance on best practices and troubleshooting. The current design which, I’ve implemented a custom Authorization Plugin for step-up authentication, which is loaded by Authorization Services at the loginwindow (inside SecurityAgent). This plugin acts as an XPC client and connects to a custom XPC daemon. Setup Details 1. XPC Daemon Runs as root (LaunchDaemon) Not sandboxed (my understanding is that root daemons typically don’t run sandboxed—please correct me if this is wrong) Mach service: com.roboInc.AuthXpcDaemon Bundle identifier: com.roboInc.OfflineAuthXpcDaemon 2. Authorization Plugin Bundle identifier: com.roboInc.AuthPlugin Loaded by SecurityAgent during login 3. Code Signing Both plugin and daemon are signed using a development certificate What I’m Trying to Achieve I want to secure the XPC communication so that: The daemon only accepts connections from trusted clients The plugin only connects to the legitimate daemon Communication is protected against unauthorized access The Issue I'm facing I attempted to validate code signatures using: SecRequirementCreateWithString SecCodeCopyGuestWithAttributes SecCodeCheckValidity However, validation consistently fails with: -67050 (errSecCSReqFailed) Could you please help here What is the recommended way to securely authenticate an Authorization Plugin (running inside SecurityAgent) to a privileged XPC daemon? Since the plugin runs inside SecurityAgent, how can the daemon reliably distinguish my plugin from other plugins? What is the correct approach to building a SecRequirement in this scenario? Any guidance, examples, or pointers would be greatly appreciated. Thanks in advance!
6
0
658
Mar ’26
How to debug a Launch Daemon that requires an App Group provisioning profile for XPC communication
Hello, I am developing a macOS Launch Daemon (packaged as a bundle) that acts as an XPC server. For debugging purposes, I am trying to run the daemon's executable directly from the terminal via sudo ./mydaemon.app/Contents/MacOS/myexecutable. Initially, I added the com.apple.security.application-groups entitlement to the daemon. However, when starting the process, it failed to create the XPC service with the following errors: Unsatisfied entitlements: com.apple.security.application-groups Soft-restriction provisioning profile validation failure: Error Domain=AppleMobileFileIntegrityError Code=-413 "No matching profile found" UserInfo={NSURL=, unsatisfiedEntitlements=, NSLocalizedDescription=No matching profile found} listener failed to activate: xpc_error=[1: Operation not permitted] To resolve the profile validation failure, I registered a new App Group in the Apple Developer Portal, generated a new provisioning profile for the daemon that includes this group, and embedded it into the bundle (Contents/embedded.provisionprofile). Now, the previous profile error is gone, but I am getting a new identity conflict error, and the XPC listener still fails: Two equal instances have unequal identities. <anon<myproc_name>(501) pid=2818 AUID=501> and <anon<myproc_name>(501)(262) pid=2818 AUID=262> listener failed to activate: xpc_error=[1: Operation not permitted] My questions are: What exactly causes the Two equal instances have unequal identities error? I noticed the Audit UID difference (AUID=501 vs AUID=262). Why does NSXPCListener still fail with Operation not permitted? What is the recommended workflow for debugging a Launch Daemon that requires an App Group provisioning profile for XPC communication? Thank you in advance!
2
0
359
Apr ’26
TelephonyMessagingKit drops first SMS at cold launch — race between client XPC handler registration and server pending flush
Hi all, I'm the developer of OV Message, an end-to-end encrypted SMS messaging app already shipped on Google Play (Android, where it natively encrypts SMS content). The iOS port aims to be the default carrier-messaging app, handling SMS, MMS, and RCS through TelephonyMessagingKit with the com.apple.developer.carrier-messaging-app entitlement under the EU programme. While testing the cold-launch flow on iOS 26.x, I've hit a reproducible bug that silently drops the first SMS/MMS/RCS that wakes the app, and I'd like to confirm whether other devs working with this API see the same. The bug When a default carrier-messaging app is force-killed and a message arrives, iOS correctly: Routes the message via CommCenter (IMS in my case — SFR France) Wakes the app in background (state = .background at didFinishLaunchingWithOptions) Acquires a TelephonyMessaging runningboard assertion on the app But CommCenter then pushes the pending message via XPC before the client TMK library has finished registering its messageHandlersByID dictionary. Result: client responds Received unhandled request, server logs TMKXPCError Code=2, message is dropped, never delivered to for await in incomingMessageNotifications. Subsequent messages (with the app warm) work fine. Native log sequence (from idevicesyslog with the Telephony logging profile) T+0.000 CommCenter: SMS arrives via IMS (k3GPP) T+0.003 CommCenter: Default app is set to com.example.app T+0.004 CommCenter: Attempting to launch and acquire process assertion T+0.083 CommCenter: Notifying SMS message received, target: bundleID=... T+0.085 CommCenter(TMK): There are no client connections matching, pending message [~125 ms — app boots] T+0.128 App(TMK): Configuring connection T+0.128 App(TMK): Pinging remote end T+0.130 CommCenter(TMK): Received new connection from PID T+0.130 CommCenter(TMK): New incoming connection, flushing pending messages (1) ← server flushes T+0.130 App(TMK): Received unhandled request ← client not ready T+0.131 CommCenter(TMK): Failed to send pending message: TMKXPCError Code=2 T+0.132 App(TMK): Registered for IncomingMessageNotification (smsReceived) ← ~2 ms too late The race window between Pinging remote end (client) and Registered for IncomingMessageNotification (client) is 2–7 ms across my measurements. CommCenter considers the connection ready as soon as the ping completes, but the client library populates messageHandlersByID slightly after, so the dispatch fails. Minimal reproduction I built a ~50-line Swift app to confirm this isn't specific to OV Message. UIKit AppDelegate, single for await in TelephonyMessagingSession.shared.smsService.incomingMessageNotifications started in didFinishLaunchingWithOptions. No SwiftUI, no other modules, no Darwin notifications. Just TMK. Steps: Build & install on iPhone iOS 26.x with carrier-messaging-app entitlement (auto-provisioned in iOS 26) Settings → Apps → Default Messaging → select the test app Force-kill, then send 2 SMS in rapid succession from another phone Wait 30 s, open the app — log shows only the 2nd SMS Same result: the 1st SMS is gone. I've reproduced this consistently dozens of times. Source code (Swift + xcodegen project.yml): https://gist.github.com/ovmessage/fbc529292a65222191bec6ce5e5a4275 What I've tried Task.detached(priority: .userInitiated) to decouple the for await from main thread scheduling — no effect (race is internal to TMK lib, before our scheduling) Pre-fetching cellularServices synchronously — no effect Subscribing MMS + RCS in parallel — no effect Direct XPCSession/xpc_connection_create_mach_service to com.apple.commcenter.tmk.xpc — Apple has marked these unavailable on iOS for 3rd-party apps (no public way to bypass the lib) I've also done runtime introspection of the TMK framework via Mirror, which confirms the architecture: a single XPCConnection.messageHandlersByID dict shared by smsReceived, mmsReceived, rcsReceivedNotification — all four entries (incl. serviceStatusNotification) are populated after the XPC ping. So the same race affects SMS, MMS, and RCS equally. Suggested fixes (Apple-side) Either: Server (CommCenter): defer flushing pending messages until the client confirms its handlers are registered (extra XPC handshake message) Client (TelephonyMessagingKit): register messageHandlersByID entries before sending Pinging remote end, so they exist when the server starts flushing Buffer client-side: cache messages received before handler registration completes, dispatch on attach Filed in Feedback Assistant FB[YOUR_FB_NUMBER_HERE] Question for fellow devs If you're also building with carrier-messaging-app entitlement (Beeper, Google Messages on iOS, anyone in the EU programme), can you confirm whether you see the same race? Especially interested in whether: It happens with non-IMS carriers (mine is SFR France, IMS-routed via SIP) iOS 26.1 / 26.2 changed the timing Anyone has found a workaround I haven't tried Thanks.
3
0
341
May ’26
XPC connection broken on app & extension upgrade
After an app update replaces our extension with the new version, the XPC connection between the app and the extension fails to work roughly 20% of the time. Once it's broken, it stays broken — our reconnect/retry logic doesn't recover it, stopping and starting the extension doesn't recover it, and the only thing that fixes it is a full machine restart. This obviously isn't ideal. I've seen a few other threads describing the same or a very similar issue: https://developer.apple.com/forums/thread/728063 https://developer.apple.com/forums/thread/779395 https://developer.apple.com/forums/thread/742992 On a broken upgrade cycle, when we run: sudo launchctl print system/NetworkExtension.com.company.example.app.filter.5.5.0.2248 the endpoints entry is missing from the output entirely. On a working upgrade cycle, the same command shows endpoints = {} is present. So it looks like our XPC service isn't actually getting registered with launchd in the broken case. We've tried various changes to our connection logic, but nothing prevents the issue — random upgrades still end up broken with no obvious cause. Is there a known way to recover the XPC registration without requiring a machine restart?
1
0
267
May ’26
Securely passing credentials from Installer plug-in to newly installed agent — how to authenticate the caller?
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 ?
Replies
5
Boosts
0
Views
1.7k
Activity
Oct ’25
Mac: Best way to distinguish native app process and script process spawned from executable (e.g. python node) through process_id
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.
Replies
1
Boosts
0
Views
300
Activity
Sep ’25
XPC codesign requirement crashes application
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/*
Replies
2
Boosts
0
Views
439
Activity
Sep ’25
SSO Extension Fails XPC Connection to System Daemon (mach-lookup exception used)
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!
Replies
2
Boosts
0
Views
335
Activity
Oct ’25
XPC: too many nested collections when explicitly decoding a single collection on macOS 12.7 (not on macOS Tahoe)
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?
Replies
2
Boosts
0
Views
352
Activity
Oct ’25
XPC Service Installed Outside App Doesn't Set Responsible
On macOS 15.7.1 I'm trying to install an XPC service outside the app (Developer ID). It mostly seems to go ok, but when I set Launch Constraints on Responsible, AMFI complains of a violation, saying the service is responsible for itself, and fails to launch. Removing that constraint (or adding the service itself to the constraint) works fine. The service is an optional download, and installed to /Users/Shared with a LaunchAgent specifying the MachService. The service is correctly launched and seems to pass all codesigning, notarization, and other checks, but the Responsible isn't set to the "calling" app. Is this broken, or working as intended?
Replies
3
Boosts
0
Views
796
Activity
Nov ’25
Hosting x86 Audio Units on Silicon Mac
My app encountered problems when trying to open an x86 audioUnit v2 on a Silicon Mac (although Rosetta is installed). There seems to be a XPC connection issue with the AUHostingService that I don't know how to fix. I observed other host apps opening the same plugins without problem, so there is probably something wrong or incompatible in my codes. I noticed that: The issue occurs whether or not the app is sandboxed. The issue does no longer occur when the app itself runs under Rosetta. There is no error reported by CoreAudio during allocation and initialization of the audio unit. The first notified errors appears when the unit calls AudioUnitRender from the rendering callback. With most x86 plugins, the error is on first call: kAudioUnitErr_RenderTimeout and on any subsequent call: kAudioComponentErr_InstanceInvalidated On the UI side, when the Cocoa View is loaded, it appears shortly, then disappears immediately leaving its superview empty. With another x86 plugin, the Cocoa View is loaded normally, but CoreAudio still emits kAudioUnitErr_NoConnection from AudioUnitRender, whether the view has been loaded or not, and the plugin produces no sound. I also find these messages in the console (printed in that order): CLIENT ERROR: RemoteAUv2ViewController does not override - and thus cannot react to catastrophic errors beyond logging them AUAudioUnit_XPC.mm:641 Crashed AU possible component description: aumu/Helm/Tyte My app uses the AUv2 API and I suspect that working with the AUv3 API would spare me these problems. However, considering how my audio system is built (audio units are wrapped into C++ classes and most connections between units are managed on the fly from the rendering callback), it would be a lot of work to convert, and I’m even not sure that all I do with the AUv2 API would be possible with the AUv3 API. I could possibly find an intermediate solution, but in the immediate future I'm looking for the simplest and fastest possible fix. If I cannot find better, I see two fallback options: In this part of the doc: “Beginning with macOS 11, the system loads audio units into a separate process that depends on the architecture or host preference”, does “host preference” means that it would be possible to disable the “out of process” behavior, for example from the app entitlements or info.plist? Otherwise, as a last resort, I could completely disable the use of x86 audioUnits when my app runs under ARM64, for at least making things cleaner. But the Audio Component API doesn’t give any info about the plugin architecture, how could I found it? Any tip or idea about this issue will be much appreciated. Thanks in advance!
Replies
2
Boosts
0
Views
1.3k
Activity
Nov ’25
How many connections can an XPC service have?
For example, let’s propose an XPC service that can connect to websites. Suppose that I want to connect to Apple.com, microsoft.com, and ibm.com. Can 3 service objects be made between the service and client? Or does the service have to return an ID for each web connection, with the client needing to specify which connection ID along with a command?
Replies
1
Boosts
0
Views
152
Activity
Nov ’25
Can an XPC service send a response in piecemeal?
Just trying to understand the documentation. Obviously, we can send a request to the service to return all the data at once. Can the data arrive in pieces, involving either multiple async callbacks or a Combine Publisher?
Replies
1
Boosts
0
Views
158
Activity
Nov ’25
Submitting an App using Chromium Embedded Framework (CEF) to the Mac App Store
Hi, We have several Apps that use CEF internally for real-time offscreen HTML rendering. Specifically, we have a framework with an embedded XPC service that itself uses CEF to render HTML and sends the resulting IOSurface back to the host App via XPC for rendering in a Metal pipeline. So far our Apps have only been available as a direct download, but recently we have been trying to submit one of them to the MAS and have run into several issues, CEF being one of them. The core of the issue seems to be that submission to the MAS requires that all executables, including XPC services, be signed with the sandbox entitlement. After enabling the sandbox on the host App, my XPC service with CEF continued to function as before. However, after signing the XPC service with the sandbox entitlement, it stopped working. After some research, it seems that the issue here is that the XPC service once signed with the entitlement is running in its own sandbox, and because CEF uses global Mach ports for internal communication, this then fails. Further, I have read from other developers that even if these issues are overcome by e.g. modifying CEF, they have been rejected by the review team because CEF uses some private API calls. So my question is, does anyone have concrete information on whether or not it will be possible to successfully submit an App using CEF in this way (App > Framework > XPC > CEF) for publication on the MAS? Further, as an alternative I have been looking at WebKit, specifically WKWebView and calling "takeSnapshot", as this seems to be the only documented way to retrieve pixels. However, it seems that this method is not designed for real-time rendering. Assuming that CEF is a non-starter for the MAS, is there anything specific that Apple recommends for real-time offscreen HTML rendering? Cheers, Dave Lincoln
Replies
0
Boosts
0
Views
450
Activity
Nov ’25
Reconnect to network extension after network extension crush/restart
https://developer.apple.com/documentation/NetworkExtension/filtering-network-traffic App example not auto reconnect after network extension crush. what need to add for auto reconnect when network extension restart?
Replies
1
Boosts
0
Views
174
Activity
Jan ’26
How can I create a more complex XPCPeerRequirement?
I have been updating some NSXPCConnection code in my macOS 26 app (not sandboxed) to use XPCSession and friends instead. And it is working well and the experience has been generally good. But I have run into a problem when using XPCSession.setPeerRequirement() which I really want to use. It works well when I use something simple like XPCPeerRequirement.isFromSameTeam() but I want to check some more requirements and also use the code from multiple apps (but same team). That is, I want to check for multiple identifiers and team ID and version (and perhaps also in the future that the certificate is a Developer ID). And previously I would use SecRequirementCreateWithString with an entitlement string conceptually like this: var entitlement = "anchor apple generic and (" entitlement += "identifier idA" entitlement += " or identifier idB" entitlement += ")" entitlement += " and certificate leaf[subject.OU] = TeamID" entitlement += #" and info [CFBundleShortVersionString] >= "1.0""# and it works just as it should when creating and using that SecRequirement so I don't think that there is anything particularly wrong with the entitlement. And I had hoped that I could use the same string with XPCPeerRequirement.hasEntitlement(entitlement) but it doesn't work (I get a general "Peer forbidden" error). So I think that I don't really understand what sort of entitlement that hasEntitlement() wants. And also I don't really understand the other ways available to create a XPCPeerRequirement. I have also tried to use a XPCDictionary with XPCPeerRequirement(lightweightCodeRequirements:) but I can't get that to work either (and it seems a bit wrong to have to drop down to use e.g. xpc_object_t with new modern API:s). So my question is: is it possible to create a XPCPeerRequirement with an entitlement like above and, in that case, how? Or is there some other work-around to use XPCSession.setPeerRequirement() with a more complex requirement, e.g. is there a way to combine multiple XPCPeerRequirements into one? Thank you for reading this. /Peter
Replies
1
Boosts
0
Views
525
Activity
Feb ’26
Issue with XPC communication between Network Extension and host application
Hello, I need to develop a Network Extension (Transparent Proxy) that sends data to the host application for analysis. Network Extension - XPC client Host application - XPC service I am trying to implement it with XPC. However, when attempting to connect, I see the following error in the system logs on client side. [0x1015a2050] failed to do a bootstrap look-up: xpc_error=[3: No such process] I assume the problem occurs because the Network Extension cannot find the registered XPC service. On the service side, I see the following message in the logs: 2026-02-24 13:15:36.419345+0300 localhost fgstnehost[58884]: (libxpc.dylib) [com.apple.xpc:connection] [0x100bdee70] activating connection: mach=true listener=true peer=false name=TEAM_ID.group.app_id.netfilter.xpc Entitlements Network Extension: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.developer.networking.networkextension</key> <array> <string>app-proxy-provider-systemextension</string> </array> <key>com.apple.security.application-groups</key> <array> <string>TEAM_ID.group.app_id.netfilter</string> </array> <key>com.apple.security.app-sandbox</key> <true/> <key>com.apple.security.xpc.mach-lookup.global-name</key> <array> <string>TEAM_ID.group.app_id.netfilter.xpc</string> </array> </dict> </plist> Entitlements host application: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.developer.networking.networkextension</key> <array> <string>app-proxy-provider-systemextension</string> </array> <key>com.apple.developer.system-extension.install</key> <true/> <key>com.apple.security.application-groups</key> <array> <string>TEAM_ID.group.app_id.netfilter</string> </array> <key>com.apple.security.app-sandbox</key> <true/> <key>com.apple.security.xpc.mach-service.name</key> <array> <string>TEAM_ID.group.app_id.netfilter.xpc</string> </array> </dict> </plist> Server.m @interface XPCServer () @property (nonatomic, strong) NSXPCListener *listener; @end @implementation XPCServer - (instancetype) init { self = [super init]; if (self != nil) { _listener = [[NSXPCListener alloc] initWithMachServiceName: XPC_SERVICE_ID]; _listener.delegate = self; } return self; } - (void) start { [self.listener resume]; } - (BOOL) listener:(NSXPCListener *) listener shouldAcceptNewConnection:(NSXPCConnection *) newConnection { return YES; } @end Client.m @interface XPCClient () @property (nonatomic, strong) NSXPCConnection *connection; @end @implementation XPCClient - (void) connect { self.connection = [[NSXPCConnection alloc] initWithMachServiceName: XPC_SERVICE_ID options: NSXPCConnectionPrivileged]; self.connection.invalidationHandler = ^{ [[OSLogger sharedInstance] error: "XPCClient: connection can not be formed or the connection has terminated and may not be re-established"]; }; self.connection.interruptionHandler = ^{ [[OSLogger sharedInstance] error: "XPCClient: the remote process exits or crashes"]; }; [self.connection resume]; } @end What could be the root cause of this issue? Are there any recommendations for implementing IPC between a Network Extension and aß Host Application? Thank you in advance.
Replies
2
Boosts
0
Views
390
Activity
Feb ’26
Trouble creating an XPC service for out-of-process rendering
I'm working on an editor for Bevy games and wanted the following workflow: Launch the game process Host a Metal view for the game's render target Use an XPC service to transfer an MTLSharedTextureHandle Keep the connection for editor/game communication and hot reload As such I created the following editor service: public let XPCEditorServiceName = "org.bevy.editor" public enum XPCEditorMessage: Codable { case ping } public enum XPCEditorReply: Codable { case pong } extension XPCListener { static let bevy = try! XPCListener(service: XPCEditorServiceName) { request in request.accept(XPCEditorService.init) } } struct XPCEditorService: XPCPeerHandler { let session: XPCSession private func handle(_ message: XPCEditorMessage) -> XPCEditorReply? { switch message { case .ping: return .pong } } func handleIncomingRequest(_ message: XPCReceivedMessage) -> (any Encodable)? { do { return handle(try message.decode()) } catch { return nil } } func handleCancellation(error: XPCRichError) { print(error) } } and I initialize it in my app's App initializer: // Launch the XPC service print(XPCListener.bevy) I wanted to test this using an executable target with the following main.swift: let session = try XPCSession(xpcService: XPCEditorServiceName) let response: XPCEditorReply = try session.sendSync(XPCEditorMessage.ping) print("Connected to editor!") The editor prints Listener<org.bevy.editor>(Active) but the game fails with Underlying connection was invalidated. Reason: Connection init failed at lookup with error 3 - No such process What am I doing wrong? PS. Would also appreciate an example of sending & rendering the MTLSharedTextureHandle both in editor & game.
Replies
2
Boosts
0
Views
233
Activity
Feb ’26
Current wisdom on multiple XPC services in a System Extension?
I'm following up on a couple of forum threads from 2020 to get more clarity on the current guidance for supporting multiple XPC services in system extensions. For context, I'm trying to create a system extension that contains both an Endpoint Security client and a Network Extension filter, and I'm seeing indications that the system may not expect this and doesn't handle it smoothly. First: Previous guidance indicated that the system would automatically provide a Mach service named <TeamID>.<BundleID>.xpc to use for communicating with the system extension. However, the SystemExtension man page currently documents an Info.plist key called NSEndpointSecurityMachServiceName and suggests that the default service name is deprecated; and in fact if this key is not set, I find a message in the Console: The extension from () is using the deprecated default mach service name. Please update the extension to set the NSEndpointSecurityMachServiceName key in the Info.plist file. I have accordingly set this key, but I wanted to confirm that this is the current best practice. Second, and more interesting: Another user was trying to do something similar and observed that the Mach service for the endpoint security client wasn't available but the NE filter was. Quinn did some research and replied that this was intended behavior, quoting the EndpointSecurity man page: "If ES extension is combined with a Network Extension, set the NEMachServiceName key in the Info.plist" (which I have also done), and concluding from this: ... if you have a combined ES and NE system extension then the Mach service provided by the NE side takes precedence. However, the current man page does not include this quoted text and says nothing about a combined ES and NE system extension. So I'm wondering about current best practice. If I do combine the ES and NE clients in a single system extension, should they each declare the Mach service name under their respective Info.plist keys? And could there be a single XPC listener for both, using the same service name under each key, or would it be better to have separate XPC listeners? Alternatively, would it be preferable to have each component in a separate system extension? (This would entail some rearchitecting of the current design.)
Replies
4
Boosts
0
Views
500
Activity
Mar ’26
Securing XPC Daemon Communication from Authorization Plugin
I'm working on securing communication between an Authorization Plugin and an XPC daemon, and I’d appreciate some guidance on best practices and troubleshooting. The current design which, I’ve implemented a custom Authorization Plugin for step-up authentication, which is loaded by Authorization Services at the loginwindow (inside SecurityAgent). This plugin acts as an XPC client and connects to a custom XPC daemon. Setup Details 1. XPC Daemon Runs as root (LaunchDaemon) Not sandboxed (my understanding is that root daemons typically don’t run sandboxed—please correct me if this is wrong) Mach service: com.roboInc.AuthXpcDaemon Bundle identifier: com.roboInc.OfflineAuthXpcDaemon 2. Authorization Plugin Bundle identifier: com.roboInc.AuthPlugin Loaded by SecurityAgent during login 3. Code Signing Both plugin and daemon are signed using a development certificate What I’m Trying to Achieve I want to secure the XPC communication so that: The daemon only accepts connections from trusted clients The plugin only connects to the legitimate daemon Communication is protected against unauthorized access The Issue I'm facing I attempted to validate code signatures using: SecRequirementCreateWithString SecCodeCopyGuestWithAttributes SecCodeCheckValidity However, validation consistently fails with: -67050 (errSecCSReqFailed) Could you please help here What is the recommended way to securely authenticate an Authorization Plugin (running inside SecurityAgent) to a privileged XPC daemon? Since the plugin runs inside SecurityAgent, how can the daemon reliably distinguish my plugin from other plugins? What is the correct approach to building a SecRequirement in this scenario? Any guidance, examples, or pointers would be greatly appreciated. Thanks in advance!
Replies
6
Boosts
0
Views
658
Activity
Mar ’26
XPC communication between a sandboxed Network Extension and a privileged MachService
Hello, Is it possible for a Network Extension (running in its sandbox) to act as a client for an XPC service hosted by a Launch Daemon (e.g., to offload data processing)? Are there any specific sandbox restrictions or entitlement requirements for this type of XPC communication? Thank you in advance!
Replies
6
Boosts
0
Views
523
Activity
Apr ’26
How to debug a Launch Daemon that requires an App Group provisioning profile for XPC communication
Hello, I am developing a macOS Launch Daemon (packaged as a bundle) that acts as an XPC server. For debugging purposes, I am trying to run the daemon's executable directly from the terminal via sudo ./mydaemon.app/Contents/MacOS/myexecutable. Initially, I added the com.apple.security.application-groups entitlement to the daemon. However, when starting the process, it failed to create the XPC service with the following errors: Unsatisfied entitlements: com.apple.security.application-groups Soft-restriction provisioning profile validation failure: Error Domain=AppleMobileFileIntegrityError Code=-413 "No matching profile found" UserInfo={NSURL=, unsatisfiedEntitlements=, NSLocalizedDescription=No matching profile found} listener failed to activate: xpc_error=[1: Operation not permitted] To resolve the profile validation failure, I registered a new App Group in the Apple Developer Portal, generated a new provisioning profile for the daemon that includes this group, and embedded it into the bundle (Contents/embedded.provisionprofile). Now, the previous profile error is gone, but I am getting a new identity conflict error, and the XPC listener still fails: Two equal instances have unequal identities. <anon<myproc_name>(501) pid=2818 AUID=501> and <anon<myproc_name>(501)(262) pid=2818 AUID=262> listener failed to activate: xpc_error=[1: Operation not permitted] My questions are: What exactly causes the Two equal instances have unequal identities error? I noticed the Audit UID difference (AUID=501 vs AUID=262). Why does NSXPCListener still fail with Operation not permitted? What is the recommended workflow for debugging a Launch Daemon that requires an App Group provisioning profile for XPC communication? Thank you in advance!
Replies
2
Boosts
0
Views
359
Activity
Apr ’26
TelephonyMessagingKit drops first SMS at cold launch — race between client XPC handler registration and server pending flush
Hi all, I'm the developer of OV Message, an end-to-end encrypted SMS messaging app already shipped on Google Play (Android, where it natively encrypts SMS content). The iOS port aims to be the default carrier-messaging app, handling SMS, MMS, and RCS through TelephonyMessagingKit with the com.apple.developer.carrier-messaging-app entitlement under the EU programme. While testing the cold-launch flow on iOS 26.x, I've hit a reproducible bug that silently drops the first SMS/MMS/RCS that wakes the app, and I'd like to confirm whether other devs working with this API see the same. The bug When a default carrier-messaging app is force-killed and a message arrives, iOS correctly: Routes the message via CommCenter (IMS in my case — SFR France) Wakes the app in background (state = .background at didFinishLaunchingWithOptions) Acquires a TelephonyMessaging runningboard assertion on the app But CommCenter then pushes the pending message via XPC before the client TMK library has finished registering its messageHandlersByID dictionary. Result: client responds Received unhandled request, server logs TMKXPCError Code=2, message is dropped, never delivered to for await in incomingMessageNotifications. Subsequent messages (with the app warm) work fine. Native log sequence (from idevicesyslog with the Telephony logging profile) T+0.000 CommCenter: SMS arrives via IMS (k3GPP) T+0.003 CommCenter: Default app is set to com.example.app T+0.004 CommCenter: Attempting to launch and acquire process assertion T+0.083 CommCenter: Notifying SMS message received, target: bundleID=... T+0.085 CommCenter(TMK): There are no client connections matching, pending message [~125 ms — app boots] T+0.128 App(TMK): Configuring connection T+0.128 App(TMK): Pinging remote end T+0.130 CommCenter(TMK): Received new connection from PID T+0.130 CommCenter(TMK): New incoming connection, flushing pending messages (1) ← server flushes T+0.130 App(TMK): Received unhandled request ← client not ready T+0.131 CommCenter(TMK): Failed to send pending message: TMKXPCError Code=2 T+0.132 App(TMK): Registered for IncomingMessageNotification (smsReceived) ← ~2 ms too late The race window between Pinging remote end (client) and Registered for IncomingMessageNotification (client) is 2–7 ms across my measurements. CommCenter considers the connection ready as soon as the ping completes, but the client library populates messageHandlersByID slightly after, so the dispatch fails. Minimal reproduction I built a ~50-line Swift app to confirm this isn't specific to OV Message. UIKit AppDelegate, single for await in TelephonyMessagingSession.shared.smsService.incomingMessageNotifications started in didFinishLaunchingWithOptions. No SwiftUI, no other modules, no Darwin notifications. Just TMK. Steps: Build & install on iPhone iOS 26.x with carrier-messaging-app entitlement (auto-provisioned in iOS 26) Settings → Apps → Default Messaging → select the test app Force-kill, then send 2 SMS in rapid succession from another phone Wait 30 s, open the app — log shows only the 2nd SMS Same result: the 1st SMS is gone. I've reproduced this consistently dozens of times. Source code (Swift + xcodegen project.yml): https://gist.github.com/ovmessage/fbc529292a65222191bec6ce5e5a4275 What I've tried Task.detached(priority: .userInitiated) to decouple the for await from main thread scheduling — no effect (race is internal to TMK lib, before our scheduling) Pre-fetching cellularServices synchronously — no effect Subscribing MMS + RCS in parallel — no effect Direct XPCSession/xpc_connection_create_mach_service to com.apple.commcenter.tmk.xpc — Apple has marked these unavailable on iOS for 3rd-party apps (no public way to bypass the lib) I've also done runtime introspection of the TMK framework via Mirror, which confirms the architecture: a single XPCConnection.messageHandlersByID dict shared by smsReceived, mmsReceived, rcsReceivedNotification — all four entries (incl. serviceStatusNotification) are populated after the XPC ping. So the same race affects SMS, MMS, and RCS equally. Suggested fixes (Apple-side) Either: Server (CommCenter): defer flushing pending messages until the client confirms its handlers are registered (extra XPC handshake message) Client (TelephonyMessagingKit): register messageHandlersByID entries before sending Pinging remote end, so they exist when the server starts flushing Buffer client-side: cache messages received before handler registration completes, dispatch on attach Filed in Feedback Assistant FB[YOUR_FB_NUMBER_HERE] Question for fellow devs If you're also building with carrier-messaging-app entitlement (Beeper, Google Messages on iOS, anyone in the EU programme), can you confirm whether you see the same race? Especially interested in whether: It happens with non-IMS carriers (mine is SFR France, IMS-routed via SIP) iOS 26.1 / 26.2 changed the timing Anyone has found a workaround I haven't tried Thanks.
Replies
3
Boosts
0
Views
341
Activity
May ’26
XPC connection broken on app & extension upgrade
After an app update replaces our extension with the new version, the XPC connection between the app and the extension fails to work roughly 20% of the time. Once it's broken, it stays broken — our reconnect/retry logic doesn't recover it, stopping and starting the extension doesn't recover it, and the only thing that fixes it is a full machine restart. This obviously isn't ideal. I've seen a few other threads describing the same or a very similar issue: https://developer.apple.com/forums/thread/728063 https://developer.apple.com/forums/thread/779395 https://developer.apple.com/forums/thread/742992 On a broken upgrade cycle, when we run: sudo launchctl print system/NetworkExtension.com.company.example.app.filter.5.5.0.2248 the endpoints entry is missing from the output entirely. On a working upgrade cycle, the same command shows endpoints = {} is present. So it looks like our XPC service isn't actually getting registered with launchd in the broken case. We've tried various changes to our connection logic, but nothing prevents the issue — random upgrades still end up broken with no obvious cause. Is there a known way to recover the XPC registration without requiring a machine restart?
Replies
1
Boosts
0
Views
267
Activity
May ’26