i am trying to create a daemon with xpc for my app by referring to https://github.com/alienator88/HelperToolApp but i keep getting XPC remote proxy error: Couldn’t communicate with a helper application. All the identifiers all correct but the helper code is not reached.
Processes & Concurrency
RSS for tagDiscover how the operating system manages multiple applications and processes simultaneously, ensuring smooth multitasking performance.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I am building an app that uses the SMAppService to register a LaunchDaemon that is bundled with my .app. I've got a priming flow created which walks the user through approving the service so that it will start on login.
However, I need to also be able to upgrade this background service if the user updates the app. To do this, I think I need to call unregisterAndReturnError and then registerAndReturnError.
From my testing, this seems to work correctly, but I have a concern. Will the user ever be prompted to re-authorize the LaunchDaemon that I am registering? If so, under what circumstances will that happen, and what does it look like (so that I can guide the user through it)?
For this code:
let status = try await container.accountStatus()
Seeing this error:
2025-05-08 15:32:00.945731-0500 localhost myAgent[2661]: (myDaemon.debug.dylib) [com.myDaemon.cli:networking] Error Domain=CKErrorDomain Code=6 "Error connecting to CloudKit daemon. This could happen for many reasons, for example a daemon exit, a device reboot, a race with the connection inactivity monitor, invalid entitlements, and more. Check the logs around this time to investigate the cause of this error." UserInfo={NSLocalizedDescription=Error connecting to CloudKit daemon. This could happen for many reasons, for example a daemon exit, a device reboot, a race with the connection inactivity monitor, invalid entitlements, and more. Check the logs around this time to investigate the cause of this error., CKRetryAfter=5, CKErrorDescription=Error connecting to CloudKit daemon. This could happen for many reasons, for example a daemon exit, a device reboot, a race with the connection inactivity monitor, invalid entitlements, and more. Check the logs around this time to investigate the cause of this error., NSUnderlyingError=0x600001bfc270 {Error Domain=NSCocoaErrorDomain Code=4099 UserInfo={NSDebugDescription=
I initially started the this process as System Daemon to see what would happen (which obviously does not have CloudKit features). Then moved it back to /Library/LaunchAgents/ and can't get rid of that error.
I see also following message from CloudKit daemon:
Ignoring failed attempt to get container proxy for <private>: Error Domain=NSCocoaErrorDomain Code=4099 UserInfo={NSDebugDescription=<private>}
Automatically retrying getting container proxy due to error for <private>: Error Domain=NSCocoaErrorDomain Code=4099 UserInfo={NSDebugDescription=<private>}
XPC connection interrupted for <private>
And this error for xpc service:
[0x130e074b0] failed to do a bootstrap look-up: xpc_error=[3: No such process]
If I start the same cli process directly from XCode, then it works just fine.
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?
Say I want to sync a toggle in my app with SMAppService's .status property.
If the status changes from my app I can track it. But if user toggles it from System Settings, I don't see a notification so then the UI in my app is out of date.
The status property is not key value observable and there doesn't appear to be a SMAppServiceStatusDidChangeNotification ?
I can re-read it every time my app will become active but feels kind of wrong to do it this way.
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 used C APIs to create a XPC server(mach service) as a launch daemon. I use dispatch_source_create () followed by dispatch_resume() to start the listener. I dont have any code for cleaning up memory.
I want to make sure that the XPC server is shutdown gracefully, without any memory leaks.
I know that launchd handles the cycle and the XPC framework takes care of XPC objects.
But do I need to do additional cleanup when the XPC listener is shutdown ?
I posted here https://developer.apple.com/forums/thread/805554?page=1#867766022 but posting again for visibility (and let me know how I can file a bug)
There was a response in that thread that said you could use the childProgress system to help updating progresses to keep the backgroundTask alive.
What I've found is that using childProgresses results in more terminations than if you just updated the progress directly.
Here is my setups to test this
A BGContinuedProcessingTask that uses URLSessions to upload, and registers the task.progress with the Urlsession Progress
Same, but the task.progress gets updated via a UrlSession Callback
The second is MUCH more stable out in the field in cellular settings, the first fails extremely frequently.
My suspicion is that in the documentation here https://developer.apple.com/documentation/foundation/progress#Reporting-Progress-for-Multiple-Operations
it explicitly states
The completedUnitCount property for a containing progress object only updates when the suboperation is 100% complete. The fractionCompleted property for a containing progress object updates continuously as work progresses for all suboperations.
I wonder if BGContinuedProcessingTask is only looking at completedUnitCount for progress, and not fractionCompleted?
In either case, I would love to use the childProgresses because there are bugs with retries by updating the progress manually, so would love some help resolving this, Thanks!
I've tuned my task to be decently resilient, but I found a few issues that caused it to expire regularly.
excessive CPU usage -> I'm actually running it behind ReactNative, and I found an issue where I was still updating ReactNative and thus it was keeping it alive the entire time the task was running. Removing this update helped improve stability
not updating progress frequently enough ( see https://developer.apple.com/forums/thread/809182?page=1#868247022)
My feature request is, would it be possible to get a reason the task was expired in task.expirationHandler? That would be helpful for both the user and for debugging why the task was expired. Thanks!
Hi. I'm trying to learn macOS app development. i'm trying to run unix commands:
func execute(_ command: String) throws -> String {
let process = Process()
let pipe = Pipe()
process.executableURL = URL(fileURLWithPath: "/bin/bash")
process.arguments = ["-c", command]
process.standardOutput = pipe
// process.standardError
try process.run()
process.waitUntilExit()
guard let data = try pipe.fileHandleForReading.readToEnd() else {
throw CommandError.readError
}
guard let output = String(data: data, encoding: .utf8) else {
throw CommandError.invalidData
}
process.waitUntilExit()
guard process.terminationStatus == 0 else {
throw CommandError.commandFailed(output)
}
return output
}
when try to run "pgrep" in sandbox mode ON, i get:
sysmon request failed with error: sysmond service not found error. if i turn it off it works. i don't know what to do. anyone can help me out?
For some reason, after invoking an unrelated dlclose() call to unload any .dylib that had previously been loaded via dlopen(..., RTLD_NOW), the subsequent call to task_info(mach_task_self(), TASK_DYLD_INFO, ...) syscall returns unexpected structure in dyld_uuid_info image_infos->uuidArray, that, while it seems to represent an array of struct dyld_uuid_info elements, there is only 1 such element (dyld_all_image_infos *infos->uuidArrayCount == 1) and the app crashes when trying to access dyld_uuid_info image->imageLoadAddress->magic, as image->imageLoadAddress doesn't seem to represent a valid struct mach_header structure address (although it looks like a normal pointer within the process address space. What does it point to?).
This reproduces on macOS 15.4.1 (24E263)
Could you please confirm that this is a bug in the specified OS build, or point to incorrect usage of the task_info() API?
Attaching the C++ file that reproduces the issue to this email message
It needs to be built on macOS 15.4.1 (24E263) via Xcode or just a command line clang++ compiler. It may crash or return garbage, depending on memory layout, but on this macOS build it doesn’t return a correct feedfacf magic number for the struct mach_header structure.
Thank you
Feedback Assistant reference: FB18431345
//On `macOS 15.4.1 (24E263)` create a C++ application (for example, in Xcode), with the following contents. Note, that this application should crash on this macOS build. It will not crash, however, if you either:
//1. Comment out `dlclose()` call
//2. Change the order of the `performDlOpenDlClose()` and `performTaskInfoSyscall()` functions calls (first performTaskInfoSyscall() then performDlOpenDlClose()).
#include <iostream>
#include <dlfcn.h>
#include <mach/mach.h>
#include <mach-o/dyld_images.h>
#include <mach-o/loader.h>
void performDlOpenDlClose() {
printf("dlopen/dlclose function\n");
printf("Note: please adjust the path below to any real dylib on your system, if the path below doesn't exist!\n");
std::string path = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libswiftDemangle.dylib";
printf("Dylib to open: %s\n", path.c_str());
void* handle = ::dlopen(path.c_str(), RTLD_NOW);
if(handle) {
::dlclose(handle);
} else {
printf("Error: %s\n", dlerror());
}
}
void performTaskInfoSyscall() {
printf("Making a task_info() syscall\n");
printf("\033[34mSource File: %s\033[0m\n", __FILE__);
task_t task = mach_task_self();
struct task_dyld_info dyld_info;
mach_msg_type_number_t size = TASK_DYLD_INFO_COUNT;
kern_return_t kr = task_info(task, TASK_DYLD_INFO, (task_info_t)&dyld_info, &size);
if (kr != KERN_SUCCESS) {
fprintf(stderr, "task_info failed: %s\n", mach_error_string(kr));
}
const struct dyld_all_image_infos* infos =
(const struct dyld_all_image_infos*)dyld_info.all_image_info_addr;
printf("version: %d, infos->infoArrayCount: %d\n", infos->version, infos->infoArrayCount);
for(uint32_t i=0; i<infos->infoArrayCount; i++) {
dyld_image_info image = infos->infoArray[i];
const struct mach_header* header = image.imageLoadAddress;
printf("%d ", i);
printf("%p ", (void*)image.imageLoadAddress);
printf("(%x) ", header->magic);
printf("%s\n", image.imageFilePath);
fflush(stdout);
}
printf("\n\n");
printf("infos->uuidArrayCount: %lu\n", infos->uuidArrayCount);
for(uint32_t i=0; i<infos->uuidArrayCount; i++) {
dyld_uuid_info image = infos->uuidArray[i];
const struct mach_header* header = image.imageLoadAddress;
printf("%d ", i);
printf("%p ", (void*)image.imageLoadAddress);
printf("(%x)\n", header->magic);
fflush(stdout);
}
printf("task_info() syscall result processing is completed\n\n");
}
int main(int argc, const char * argv[]) {
performDlOpenDlClose();
performTaskInfoSyscall();
return 0;
}
I'm looking into a newer XPC API available starting with macOS 14. Although it's declared as a low-level API I can't figure it how to specify code signing requirement using XPCListener and XPCSession. How do I connect it with xpc_listener_set_peer_code_signing_requirement and xpc_connection_set_peer_code_signing_requirement which require xpc_listener_t and xpc_connection_t respectively?
Foundation XPC is declared as a high-level API and provides easy ways to specify code signing requirements on both ends of xpc.
I'm confused with all these XPC APIs and their future:
Newer really high-level XPCListener and XPCSession API (in low-level framework???)
Low-level xpc_listener_t & xpc_connection_t -like API. Is it being replaced by newer XPCListener and XPCSession?
How is it related to High-level Foundation XPC? Are NSXPCListener and NSXPCConnection going to be deprecated and replaced by XPCListener and XPCSession??
Hello,
My app (daemon) time to time need to know list of GUI login sessions.
According to the recommendation, I am using getutxent().
https://developer.apple.com/library/archive/qa/qa1133/_index.html
However, I have faced with unclear behaviour in case of running "Migration Assistant". It can be re-created without my app.
Steps to recreate:
login as 'user #1'
start "Migration Assistant"
quit "Migration Assistant"
new login prompt will be opened
login as 'user #2'
In spite the session of 'user #1' is closed, the command line tool "who", which gathers information from /var/run/utmpx, reports opened sessions of 'user #1'.
Is it bug or feature?
Thank you in advance!
We've seen a recent increase in background terminations:
blue - System Pressure
orange - Task Timeout
I'm trying to understand the increase in system-pressure terminations, since there's no corresponding increase in memory at suspension. Are there other system resources for which iOS will terminate an app?
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
Organizer Window
Background Tasks
Hi Team,
We intend to create a custom serial dispatch queue targetting a global queue.
let serialQueue = DispatchQueue(label: "corecomm.tallyworld.serial", target: DispatchQueue.global(qos: .default))
The documentation for DispatchQueue init does not show any minimum OS versions. BUT DispatchSerialQueue init does show iOS 17.0+ iPadOS 17.0+ Mac Catalyst macOS 14.0+ tvOS 17.0+ visionOS watchOS 10.0+.
Does that mean - I will not be able to create a custom serial dispatch queue below iOS 17?
Im using the low-level C xpc api <xpc/xpc.h> and i get this error when I run it: Underlying connection interrupted. I know this error stems from the call to xpc_session_send_message_with_reply_sync(session, message, &reply_err);. I have no previous experience with xpc or dispatch and I find the xpc docs very limited and I also found next to no code examples online. Can somebody take a look at my code and tell me what I did wrong and how to fix it? Thank you in advance.
Main code:
#include <stdio.h>
#include <xpc/xpc.h>
#include <dispatch/dispatch.h>
// the context passed to mainf()
struct context {
char* text;
xpc_session_t sess;
};
// This is for later implementation and the name is also rudimentary
void mainf(void* c) {
//char * text = ((struct context*)c)->text;
xpc_session_t session = ((struct context*)c)->sess;
dispatch_queue_t messageq = dispatch_queue_create("y.ddd.main",
DISPATCH_QUEUE_SERIAL);
xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_string(message, "test", "eeeee");
if (session == NULL) {
printf("Session is NULL\n");
exit(1);
}
__block xpc_rich_error_t reply_err = NULL;
__block xpc_object_t reply;
dispatch_sync(messageq, ^{
reply = xpc_session_send_message_with_reply_sync(session,
message,
&reply_err);
if (reply_err != NULL) printf("Reply Error: %s\n",
xpc_rich_error_copy_description(reply_err));
});
if (reply != NULL)
printf("Reply: %s\n", xpc_dictionary_get_string(reply, "test"));
else printf("Reply is NULL\n");
}
int main(int argc, char* argv[]) {
// Create seperate queue for mainf()
dispatch_queue_t mainq = dispatch_queue_create("y.ddd.main",
DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t xpcq = dispatch_queue_create("y.ddd.xpc",
NULL);
// Create the context being sent to mainf
struct context* c = malloc(sizeof(struct context));
c->text = malloc(sizeof("Hello"));
strcpy(c->text, "Hello");
xpc_rich_error_t sess_err = NULL;
xpc_session_t session = xpc_session_create_xpc_service("y.getFilec",
xpcq,
XPC_SESSION_CREATE_INACTIVE,
&sess_err);
if (sess_err != NULL) {
printf("Session Create Error: %s\n",
xpc_rich_error_copy_description(sess_err));
xpc_release(sess_err);
exit(1);
}
xpc_release(sess_err);
xpc_session_set_incoming_message_handler(session, ^(xpc_object_t message) {
printf("message recieved\n");
});
c->sess = session;
xpc_rich_error_t sess_ac_err = NULL;
xpc_session_activate(session, &sess_ac_err);
if (sess_err != NULL) {
printf("Session Activate Error: %s\n",
xpc_rich_error_copy_description(sess_ac_err));
xpc_release(sess_ac_err);
exit(1);
}
xpc_release(sess_ac_err);
xpc_retain(session);
dispatch_async_f(mainq, (void*)c, mainf);
xpc_release(session);
dispatch_main();
}
XPC Service code:
#include <stdio.h>
#include <xpc/xpc.h>
#include <dispatch/dispatch.h>
int main(void) {
xpc_rich_error_t lis_err = NULL;
xpc_listener_t listener = xpc_listener_create("y.getFilec",
NULL,
XPC_LISTENER_CREATE_INACTIVE,
^(xpc_session_t sess){
printf("Incoming Session: %s\n", xpc_session_copy_description(sess));
xpc_session_set_incoming_message_handler(sess,
^(xpc_object_t mess) {
xpc_object_t repl = xpc_dictionary_create_empty();
xpc_dictionary_set_string(repl, "test", "test");
xpc_rich_error_t send_repl_err = xpc_session_send_message(sess, repl);
if (send_repl_err != NULL) printf("Send Reply Error: %s\n",
xpc_rich_error_copy_description(send_repl_err));
});
xpc_rich_error_t sess_ac_err = NULL;
xpc_session_activate(sess, &sess_ac_err);
if (sess_ac_err != NULL) printf("Session Activate: %s\n",
xpc_rich_error_copy_description(sess_ac_err));
},
&lis_err);
if (lis_err != NULL) {
printf("Listener Error: %s\n", xpc_rich_error_copy_description(lis_err));
xpc_release(lis_err);
}
xpc_rich_error_t lis_ac_err = NULL;
xpc_listener_activate(listener, &lis_ac_err);
if (lis_ac_err != NULL) {
printf("Listener Activate Error: %s\n", xpc_rich_error_copy_description(lis_ac_err));
xpc_release(lis_ac_err);
}
dispatch_main();
}
When using the continuation API, we're required to call resume exactly once. While withCheckedContinuation helps catch runtime issues during debugging, I'm looking for ways to catch such errors at compile time or through tools like Instruments.
Is there any tool or technique that can help enforce or detect this requirement more strictly than runtime checks? Or would creating custom abstractions around Continuation be the only option to ensure safety? Any suggestions or best practices are appreciated.
I have an app that uses background audio recording. From what others say, I have enabled the audio background mode to keep the audio session active, and this worked. But when submitting the app to the app store, the app was rejected because the audio background mode is only supposed to be used for audio playback.
How do I create this background mode while following Apple's guidelines?
I’m trying to enable Background Modes (specifically for audio, background fetch, remote notifications) in my iOS SwiftUI app, but I’m getting this error:
Provisioning profile “iOS Team Provisioning Profile: [my app]” doesn’t include the UIBackgroundModes entitlement.
On the developer website when I make the provision profile It doesnt give me the option to allow background modes.
I added it to the sign in capabilities seccion in X code and matched the bundle ID to the provision profile and certificate etc but it still runs this error because the provision profile doesnt have the entitlements..
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
Entitlements
Provisioning Profiles
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?