I have an app which contains a bundled launch agent that I register using SMAppService.agent(plistName:). I’ve packaged the launch agent executable in the typical Mac app bundle structure so I can embed a framework in it. So, the launch agent lives in Contents/SharedSupport/MyLaunchAgent.app/Contents/MacOS/MyLaunchAgent.
However, I suspect this approach might be falling afoul of the scheduler, since the taskinfo tool reports my launch agent has a requested & effective role of TASK_DEFAULT_APPLICATION (PRIO_DARWIN_ROLE_UI), rather than the TASK_UNSPECIFIED (PRIO_DARWIN_ROLE_DEFAULT) value I see with system daemons.
I tried setting the LSUIElement Info.plist key of my launch agent to YES, but this seems to have had no effect.
What’s the recommended approach here?
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
For a macOS GUI application (with a UIKit or AppKit entry point), I want to reliably capture diagnostic logs sent to stderr — especially useful when the app is launched from a terminal script or runs in the background, and traditional GUI elements (like alert dialogs) may not be viable. This is to log startup failures or even success messages for later inspection. However, when the app is launched via open MyApp.app, stderr redirection like open MyApp.app 2> log.txt does not capture any output — the file is created, but remains empty.
The only way I can capture stderr reliably is by bypassing the bundle and directly launching the binary inside with ./MyApp.app/Contents/MacOS/MyApp 2> ~/log.txt
This logs as expected, but is not the user-friendly or typical way to launch apps on macOS.
Double-clicking the app in Finder also does not show any stderr output.
Is there any recommended or supported way to redirect or access stderr output when launching a .app bundle via open, or any best practice for logging critical failures from a GUI app when terminal output isn't visible?
Topic:
App & System Services
SubTopic:
Processes & Concurrency
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;
}
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!
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?
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?
I am developing the application in Mac. My requirement is to start the application automatically when user login.
I have tried adding the plist file in launch agents, But it doesn't achieve my requirement.
Please find the code added in the launch agents
<?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>Label</key>
<string>com.sftk.secure</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/Testing.app/Contents/MacOS/Testing</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<false/>
</dict>
</plist>
I have tried by adding manually in the setting, but it was opened sometimes and closed suddenly. On open manually it works.
Please provide a solution to start the application automatically on system starts
Hi everyone,
We’re developing a macOS SwiftUI app that uses a local Swift Package (CasSherpaCore) to invoke an external compiled binary (sherpa-onnx-offline-tts) for text-to-speech synthesis using system calls. The package works flawlessly when tested from terminal or via a lightweight test C program.
However, when we invoke it from a SwiftUI app (even with Full Disk Access granted to Xcode and Terminal), we consistently get the error:
sh: /Users/xxxxxxxxxxx/SherpaONNX/sherpa-onnx/build/bin/sherpa-onnx-offline-tts: Operation not permitted
We’ve tried:
Granting Full Disk Access to Xcode and Terminal.
Removing the quarantine flag with xattr -d com.apple.quarantine.
Setting executable permission via chmod +x.
Using both system() and Process in C and Swift contexts.
Testing within a Swift Package that’s integrated into the app as a local dependency.
Running the command manually from terminal (works perfectly).
It appears that macOS (or Xcode’s runtime sandbox) is restricting execution of binaries from certain locations or contexts when launched via system() inside the app.
Questions:
Is there a specific entitlement or configuration that allows execution of local binaries from a SwiftUI macOS app?
Is this related to System Integrity Protection (SIP) or a hardened runtime limitation?
Are there best practices or alternative approaches to safely execute local TTS binaries from within a Swift app?
Any help would be deeply appreciated. This is a core feature in our project and we’re stuck at this point. Thank you so much in advance!
My app is for personal use currently, so distribution won't be a problem. It registers a privileged helper using SMAppService, and I was wondering whether there is a way to customize the authorization dialog that the system presents to the user.
My app uses SMAppService to register a privileged helper, the helper registers without errors, and can be seen in System Settings. I can get a connection to the service and a remote object proxy, but the helper process cannot be found in Activity Monitor and the calls to the proxy functions seem to always fail without showing any specific errors. What could be causing this situation?
SMAppService Error 108 "Unable to read plist" on macOS 15 Sequoia - Comprehensive Test Case
Summary
We have a fully notarized SMAppService implementation that consistently fails with Error 108 "Unable to
read plist" on macOS 15 Sequoia, despite meeting all documented requirements. After systematic testing
including AI-assisted analysis, we've eliminated all common causes and created a comprehensive test
case.
Error: SMAppServiceErrorDomain Code=108 "Unable to read plist: com.keypath.helperpoc.helper"
📋 Complete Repository: https://github.com/malpern/privileged_helper_help
What We've Systematically Verified ✅
Perfect bundle structure: Helper at Contents/MacOS/, plist at Contents/Library/LaunchDaemons/
Correct SMAuthorizedClients: Embedded in helper binary via CREATE_INFOPLIST_SECTION_IN_BINARY=YES
Aligned identifiers: Main app, helper, and plist all use consistent naming
Production signing: Developer ID certificates with full Apple notarization and stapling
BundleProgram paths: Tested both Contents/MacOS/helperpoc-helper and simplified helperpoc-helper
Entitlements: Tested with and without com.apple.developer.service-management.managed-by-main-app
What Makes This Different
Systematic methodology: Not a "help me debug" post - we've done comprehensive testing
Expert validation: AI analysis helped eliminate logical hypotheses
Reproduction case: Minimal project that demonstrates the issue consistently
Complete documentation: All testing steps, configurations, and results documented
Use Case Context
We're building a keyboard remapper that integrates with https://github.com/jtroo/kanata and needs
privileged daemon registration for system-wide keyboard event interception.
Key Questions
Does anyone have a working SMAppService implementation on macOS 15 Sequoia?
Are there undocumented macOS 15 requirements we're missing?
Is Error 108 a known issue with specific workarounds?
Our hypothesis: This appears to be a macOS 15 system-level issue rather than configuration error, since
our implementation meets all documented Apple requirements but fails consistently.
Has anyone encountered similar SMAppService issues on macOS 15, or can confirm a working
implementation?
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
Service Management
Notarization
Hello,
I have a question regarding the behavior of BGProcessingTaskRequest when the app is force-quit by the user via the App Switcher.
Based on common understanding and various discussions — including the following Apple Developer Forum threads:
Waking up an iOS app after app is … | Apple Developer Forums
Will BGAppRefreshTaskRequest will … | Apple Developer Forums
Background fetch after app is forc… | Apple Developer Forums
…it is widely understood that iOS prevents background execution (such as background fetch, push notifications, or BGTaskScheduler) after a user force-quits an app via the App Switcher.
However, in my app, I have observed that a scheduled BGProcessingTaskRequest still executes even after the app has been explicitly terminated via App Switcher. The task is scheduled using submit(_:error:), and it is clearly running some time after the app has been closed by the user.
That said, the task does run, but it appears to operate under tighter constraints — for example, it may be allowed to run for a shorter duration, and network requests appear to be more restricted compared to when the app is not force-quit.
My questions are:
Are there any documented or undocumented exceptions that allow this kind of behavior after force-quit?
Could this be a bug or a behavior change in recent iOS versions? (I am observing this on iOS 18.3, 18.4, and 18.5)
Any insights, experiences, or clarifications from Apple engineers or fellow developers would be greatly appreciated.
Thank you!
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.
my app need tracking location all the time both foreground and background. Please suggest how to prevent the app from being terminated. or detect when app is terminated.
Hello 👋
Our team added com.apple.security.temporary-exception.apple-events: com.apple.Terminal recently to our Mac app to be able to tell the terminal to execute a specific command line automatically for the user when clicking a button but we've been rejected during review because of this entitlement so for now we've deleted it and deleted the associated feature.
It concerns the following feature (see attachment).
Context:
Among other things the application enable to review pull request changes (remote) and we would like a button to automatically clone the pull request on disk when user click a button. We would like to use terminal for security reason as when cloning using git command we need ssh keys or other credential and there's no reason (rather than technical ones) that the user provide us such private information that is stored in the ~/.ssh. We prefer think the other way around and tell the user what to execute instead (no credentials involved or shared).
We referred to: https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/AppSandboxTemporaryExceptionEntitlements.html
I admit it's unclear for me if this will imply a 100% rejection or if these entitlements are deprecated.
Is "com.apple.security.temporary-exception.apple-events: com.apple.Terminal" an entitlement that is reserved for special Apple partners ?
Is it an entitlement that we should demonstrate usage first ? Or should we completely remove the feature if we distribute through the App Store ?
Is Apple advice for other APIs to develop such features (execute command line for the user) when distributing through the App Store ?
As said we've disabled the feature for now.
Thank you in advance for those who will take time to answer this,
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
when we use raise in GCD, the signal handler is executed asynchronously, whereas in pthread, it is executed synchronously as expected.
example:
#include <Foundation/Foundation.h>
#include <pthread/pthread.h>
static void HandleSignal(int sigNum, siginfo_t* signalInfo, void* userContext) {
printf("handle signal %d\n", sigNum);
printf("begin sleep\n");
sleep(3);
printf("end sleep\n");
}
void InstallSignal(void) {
static const int g_fatalSignals[] =
{
SIGABRT,
SIGBUS,
SIGFPE,
SIGILL,
SIGPIPE,
SIGSEGV,
SIGSYS,
SIGTRAP,
};
int fatalSignalsCount = sizeof(g_fatalSignals) / sizeof(int);
struct sigaction action = {{0}};
action.sa_flags = SA_SIGINFO | SA_ONSTACK;
#if defined(__LP64__)
action.sa_flags |= SA_64REGSET;
#endif
sigemptyset(&action.sa_mask);
action.sa_sigaction = &HandleSignal;
struct sigaction pre_sa;
for(int i = 0; i < fatalSignalsCount; i++) {
int sigResult = sigaction(g_fatalSignals[i], &action, &pre_sa);
}
}
void* RaiseAbort(void *userdata) {
raise(SIGABRT);
printf("signal handler has finished\n");
return NULL;
}
int main(int argc, const char * argv[]) {
InstallSignal();
dispatch_async(dispatch_get_global_queue(0, 0), ^{
raise(SIGABRT);
// abort(); // abort() is ok
RaiseAbort(nullptr);
});
// pthread is ok
// pthread_t tid;
// int ret = pthread_create(&tid, NULL, RaiseAbort, NULL);
// if (ret != 0) {
// fprintf(stderr, "create thread failed\n");
// return EXIT_FAILURE;
// }
[[NSRunLoop mainRunLoop] run];
return 0;
}
console log:
signal handler has finished
handle signal 6
begin sleep
end sleep
I'm developing a safety-critical monitoring app that needs to fetch data from government APIs every 30 minutes and trigger emergency audio alerts for threshold violations.
The app must work reliably in background since users depend on it for safety alerts even while sleeping.
Main Challenge: iOS background limitations seem to prevent consistent 30-minute intervals. Standard BGTaskScheduler and timers get suspended after a few minutes in background.
Question: What's the most reliable approach to ensure consistent 30-minute background monitoring for a safety-critical app where missed alerts could have serious consequences?
Are there special entitlements or frameworks for emergency/safety applications?
The app needs to function like an alarm clock - working reliably even when backgrounded with emergency audio override capabilities.
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
Network
AVAudioSession
Background Tasks
Hello,
We're seeing some strange crashes and noticed the following. It's unclear if related or not.
The contract for xpc_main, which internally calls dispatch_main, is This function never returns. and they are appropriately peppered with __attribute__((__noreturn__)). Documentation states:
This function “parks” the main thread and waits for blocks to be submitted to the main queue.
However, internally, dispatch_main calls pthread_exit. pthread_exit's documentation states that:
After a thread has terminated, the result of access to local (auto)
variables of the thread is undefined. Thus, references to local
variables of the exiting thread should not be used for the
pthread_exit() value_ptr parameter value.
I'd say the two contracts of This function never returns. and thread exiting with its storage released are diametrically opposed and can create nuanced issues.
Consider the following code:
struct asd {
int a;
};
struct asd* ptr;
void fff(void* ctx)
{
while(true)
{
printf("%d\n", ptr->a);
ptr->a = (ptr->a + 1);
usleep(100000);
}
}
int main(int argc, const char * argv[]) {
struct asd zxc;
zxc.a = 1;
ptr = &zxc;
dispatch_async_f(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), NULL, fff);
dispatch_main();
return 0;
}
This is a gross over-simplification of the code we have, but in the same "spirit". We have a C++ object that is created on the stack and exposes one of its members as a global pointer, with the assumption that it would never release. What I understand from This function never returns is that the calling thread remains dormant and its stack remains alive. What I understand from pthread_exit is that the thread is killed (this is verified with a debugger attached) and its stack storage is released.
Another thing that is throwing me off is that no sanitizer that is provided by clang/Xcode catches this issue. I don't see any special handling of the internal pthread_t in libdispatch to keep the stack storage alive.
Our code is more complex, but can be solved by allocating the initial object on the heap, rather than on the stack. But still I would like to understand if this is the expected behavior. Perhaps my preconception of __attribute__((__noreturn__)) is wrong, and accessing stack variables post call to a __attribute__((__noreturn__)) function is UB?
Thanks
Topic:
App & System Services
SubTopic:
Processes & Concurrency