Processes & Concurrency

RSS for tag

Discover how the operating system manages multiple applications and processes simultaneously, ensuring smooth multitasking performance.

Concurrency Documentation

Posts under Processes & Concurrency subtopic

Post

Replies

Boosts

Views

Activity

Cleanup LaunchAgents after development
I have been playing with application bundled LaunchAgents: I downloaded Apple sample code, Run the sample code as is, Tweaked the sample code a lot and changed the LaunchAgents IDs and Mach ports IDs, Created new projects with the learnings, etc. After deleting all the Xcode projects and related project products and rebooting my machine several times, I noticed the LaunchAgent are still hanging around in launchctl. If I write launchctl print-disabled gui/$UID (or user/$UID) I can see all my testing service-ids: disabled services = { "com.xpc.example.agent" => disabled "io.dehesa.apple.app.agent" => disabled "io.dehesa.sample.app.agent" => disabled "io.dehesa.example.agent" => disabled "io.dehesa.swift.xpc.updater" => disabled "io.dehesa.swift.agent" => disabled } (there are more service-ids in that list, but I removed them for brevity purposes). I can enable or disable them with launchctl enable/disable service-target, but I cannot really do anything else because their app bundle and therefore PLIST definition are not there anymore. How can I completely remove them from my system? More worryingly, I noticed that if I try to create new projects with bundled LaunchAgents and try to reuse one of those service-ids, then the LaunchAgent will refuse to run (when it was running ok previously). The calls to SMAppService APIs such .agent(plistName:) and register() would work, though.
3
0
122
May ’25
LaunchAgent can't connect to CloudKit daemon
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.
3
0
148
May ’25
Persistent font registration crashes when fonts are delivered via Apple-Hosted Background Assets
Hi everyone, I’m trying to register fonts system-wide using CTFontManagerRegisterFontURLs with the .persistent scope. The fonts are delivered through Apple-Hosted Background Assets (since On-Demand Resources are deprecated). Process-level registration works perfectly, but persistent registration triggers a system “Install Fonts” prompt, and tapping Install causes the app to crash immediately. I’m wondering if anyone has successfully used Apple-Hosted Background Assets to provide persistent, system-wide installable fonts, or if this is a current OS limitation/bug. What I Expect Fonts delivered through Apple-Hosted Background Assets should be eligible for system-wide installation Tap “Install” should install fonts into Settings → Fonts just like app-bundled or ODR fonts App should not crash Why This Matters According to: WWDC 2019: Font Management and Text Scaling Developers can build font provider apps that install fonts system-wide, using bundled or On-Demand Resources. WWDC 2025: Discover Apple-Hosted Background Assets On-Demand Resources are deprecated, and AHBAs are the modern replacement. Therefore, persistent font installation via Apple-Hosted Background Assets appears to be the intended path moving forward. Question Is this a known limitation or bug in iOS? Should .persistent font installation work with Apple-Hosted Background Assets? Do we need additional entitlement, manifest configuration, or packaging rules? Any guidance or confirmation from Apple engineers would be greatly appreciated. Additional Info I submitted a Feedback including a minimal reproducible sample project: FB21109320
3
0
177
3w
NSXPCListener only working while Debugging `listener failed to activate: xpc_error=[1: Operation not permitted]`
I am building a Mac app that launch a GUI helper app and use XPC to communicate between them. Main app start a XPC Listener using NSXPCListener(machServiceName: "group.com.mycompany.myapp.xpc") Launch the helper app Helper app connect to the XPC service and listen command from main app. What I observe is the app seems can start XPC listener while I run it via Xcode. If I run the app using TestFlight build, or via the compiled debug binary (same one that I use on Xcode), it cannot start the XPC service. Here is what I see in the Console: [0x600000ef7570] activating connection: mach=true listener=true peer=false name=group.com.mycompany.myapp.xpc [0x600000ef7570] listener failed to activate: xpc_error=[1: Operation not permitted] Both main app and helper app are sandboxed and in the same App Group - if they were not, I cannot connect the helper app to main app. I can confirm the entitlement profiles did contain the app group. If I start the main app via xcode, and then launch the helper app manually via Finder, the helper app can connect to the XPC and everything work. It is not related to Release configuration, as the same binary work while I am debugging, but not when I open the binary manually. For context, the main app is a Catalyst app, and helper app is an AppKit app. To start a XPC listener on Catalyst, I had do it in a AppKit bridge via bundle. Given the app worked on Xcode, I believe this approach can work. I just cannot figure out why it only work while I am debugging. Any pointer to debug this issue is greatly appreciated. Thanks!
3
0
117
May ’25
Phone unlock/lock detection
Hi, I'll explain my question through how whatsapp does it. When the phone is locked then whatsapp routes call through apple's native callkit When unlocked, pressing accept essentially redirects to whatsapp and then whatsapp handles the call from there. However, this component of unlock detection is what I'm not able to find any info about. Essentially, how i do it is: let isPhoneLocked = !UIApplication.shared.isProtectedDataAvailable isProtectedDataAvailable == true → device is unlocked isProtectedDataAvailable == false → device is locked The problem is that if the phone has been recently unlocked, then protected data is still available on the phone even after the lock for the next 10-40 seconds. So theres a false positive. I want there to be a foolproof and robust way to do this. And I'm not entirely sure how
3
0
104
3w
LaunchAgent (Mac) as peripheral doesn't show a pairing request.
The same code built in a regular Mac app (with UI) does get paired. The characteristic properties are [.read, .write, .notify, .notifyEncryptionRequired] The characteristic permissions are [.readEncryptionRequired, .writeEncryptionRequired] My service is primary. In the iOS app (central) I try to read the characteristic, but an error is reported: Error code: 5, Description: Authentication is insufficient.
3
0
79
2w
Can we create a bundled non-interactive macOS application which uses CFRunLoop only(instead of using NSApplicationMain to run NSRunLoop)?
I am developing a macOS non-interactive macOS application which does not show any ui. i want to block main thread and do all the work on worker thread . Once done with work in worker thread, want to unblock main thread by exiting event loop to terminate application. Because i dont want to show any UI or use any Foundation/Cocoa functionality, i am thinking of using CFRunLoop to block main thread from exiting until i finish my work in worker thread. When i tried this in a project, I am able to finish work in worker thread after block main thread using CFRunLoop. I also want this application to be a bundled application, which can be launched by double clicking on application bundle . But when i tried it in my xcode project by launching it using double clicking on application bundle, application keeps on toggling/bouncing in the dock menu with a status "Not responding". Although i am able to complete my work in worker thread. import Foundation let runLoop = CFRunLoopGetCurrent() func workerTask() { DispatchQueue.global().async { print("do its work") sleep(5) // do some work print("calling exit event loop") CFRunLoopStop(runLoop) print ("unblocking main thread") } } workerTask () // blocking main thread print ("blocked main thread") CFRunLoopRun() print ("exit") Why i am getting this application bouncing in doc menu behavior ? I tried by using NSApplicationMain instead of CFRunLoop in my project, in that case i didnt get this behavior . Does NSApplicationMain does some extra work before starting NSRunLoop which i am not doing while using CFRunLoop, which is showing this toggling/Bouncing application icon in Dock menu ? or Is this bouncing app icon issue is related to run loop i am using which is CFRunLoop ? Note : If i dont use a bundled application and use a commandline application then i am able to do all steps in worker thread and exit main thread as i wanted after finishing my work . But i need to do all this in application which can be launched using double clicking (bundled applcation). If not by using CFRunLoop, then how can i achive this ? - Create a application which shows no UI and do all work in worker thread while main thread is blocked. Once work is done unblock main thread and exit. And user should be able to launch application using double click the application icon.
3
0
420
Mar ’25
BGContinuedProcessingTask does not respect fractionCompleted to keep alive
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!
3
0
107
4d
ExtensionKit and iOS 26
It looks like ExtensionKit (and ExtensionFoundation) is fully available on iOS 26 but there is no mention about this in WWDC. From my testing, it seems as of beta 1, ExtensionKit allows the app from one dev team to launch extension provided by another dev team. Before we start building on this, can someone from Apple help confirm this is the intentional behavior and not just beta 1 thing?
3
4
256
1w
About GCD (Grand Central Dispatch) in an extension.
We are currently developing a VoIP application that supports Local Push extention. I would like to ask for your advice on how the extension works when the iPhone goes into sleep mode. Our App are using GCD (Grand Central Dispatch) to perform periodic processing within the extension, creating a cycle by it. [sample of an our source] class LocalPushProvider: NEAppPushProvider { let activeQueue: DispatchQueue = DispatchQueue(label: "com.myapp.LocalPushProvider.ActiveQueue", autoreleaseFrequency: .workItem) var activeSchecule: Cancellable? override func start(completionHandler: @escaping (Error?) -> Void) { : self.activeSchecule = self.activeQueue.schedule( after: .init(.now() + .seconds(10)), // start schedule after 10sec interval: .seconds(10) // interval 10sec ) { self.activeTimerProc() } completionHandler(nil) } } However In this App that we are confirming that when the iPhone goes into sleep mode, self.activeTimerProc() is not called at 10-second intervals, but is significantly delayed (approximately 30 to 180 seconds). What factors could be causing the timer processing using GCD not to be executed at the specified interval when the iPhone is in sleep mode? Also, please let us know if there are any implementation errors or points to note. I apologize for bothering you during your busy schedule, but I would appreciate your response.
3
0
115
Jun ’25
Are XPCSession and XPCListener incomplete(ly documented)?
I've been experimenting with the new low-level Swift API for XPC (XPCSession and XPCListener). The ability to send and receive Codable messages is an appealing alternative to making an @objc protocol in order to use NSXPCConnection from Swift — I can easily create an enum type whose cases map onto the protocol's methods. But our current XPC code validates the incoming connection using techniques similar to those described in Quinn's "Apple Recommended" response to the "Validating Signature Of XPC Process" thread. I haven't been able to determine how to do this with XPCListener; neither the documentation nor the Swift interface have yielded any insight. The Creating XPC Services article suggests using Xcode's XPC Service template, which contains this code: let listener = try XPCListener(service: serviceName) { request in request.accept { message in performCalculation(with: message) } } The apparent intent is to inspect the incoming request and decide whether to accept it or reject it, but there aren't any properties on IncomingSessionRequest that would allow the service to make that decision. Ideally, there would be a way to evaluate a code signing requirement, or at least obtain the audit token of the requesting process. (I did notice that a function xpc_listener_set_peer_code_signing_requirement was added in macOS 14.4, but it takes an xpc_listener_t argument and I can't tell whether XPCListener is bridged to that type.) Am I missing something obvious, or is there a gap in the functionality of XPCListener and IncomingSessionRequest?
3
0
955
Feb ’25
WatchConnectivity Swift 6 - Incorrect actor executor assumption
I am trying to migrate a WatchConnectivity App to Swift6 and I found an Issue with my replyHandler callback for sendMessageData. I am wrapping sendMessageData in withCheckedThrowingContinuation, so that I can await the response of the reply. I then update a Main Actor ObservableObject that keeps track of the count of connections that have not replied yet, before returning the data using continuation.resume. ... @preconcurrency import WatchConnectivity actor ConnectivityManager: NSObject, WCSessionDelegate { private var session: WCSession = .default private let connectivityMetaInfoManager: ConnectivityMetaInfoManager ... private func sendMessageData(_ data: Data) async throws -> Data? { Logger.shared.debug("called on Thread \(Thread.current)") await connectivityMetaInfoManager.increaseOpenSendConnectionsCount() return try await withCheckedThrowingContinuation({ continuation in self.session.sendMessageData( data, replyHandler: { data in Task { await self.connectivityMetaInfoManager .decreaseOpenSendConnectionsCount() } continuation.resume(returning: data) }, errorHandler: { (error) in Task { await self.connectivityMetaInfoManager .decreaseOpenSendConnectionsCount() } continuation.resume(throwing: error) } ) }) } Calling sendMessageData somehow causing the app to crash and display the debug message: Incorrect actor executor assumption. The code runs on swift 5 with SWIFT_STRICT_CONCURRENCY = complete. However when I switch to swift 6 the code crashes. I rebuilt a simple version of the App. Adding bit by bit until I was able to cause the crash. See Broken App Awaiting sendMessageData and wrapping it in a task and adding the @Sendable attribute to continuation, solve the crash. See Fixed App But I do not understand why yet. Is this intended behaviour? Should the compiler warn you about this? Is it a WatchConnectivity issue? I initially posted on forums.swift.org, but was told to repost here.
3
0
1.2k
Jan ’25
DispatchSerialQueue minimum OS support
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?
3
0
159
Jul ’25
iOS Team Provisioning Profile” Missing UIBackgroundModes Entitlement
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..
3
0
295
Jul ’25
Crash iOS 26 Beta
We are experiencing a crash in our application that only occurs on devices running iOS beta 26. It looks like a Beta problem. The crash appears to be caused by an excessive number of open File Descriptors. We identified this after noticing a series of crashes in different parts of the code each time the app was launched. Sometimes it would crash right at the beginning, when trying to load the Firebase plist file. That’s when we noticed a log message saying “too many open files,” and upon further investigation, we found that an excessive number of File Descriptors were open in our app, right after the didFinishLaunching method of the AppDelegate. We used the native Darwin library to log information about the FDs and collected the following: func logFDs() { var rlim = rlimit() if getrlimit(RLIMIT_NOFILE, &rlim) == 0 { print("FD LIMIT: soft: \(rlim.rlim_cur), hard: \(rlim.rlim_max)") } // Count open FDs before Firebase let openFDsBefore = countOpenFileDescriptors() print("Open file descriptors BEFORE Firebase.configure(): \(openFDsBefore)") } private func countOpenFileDescriptors() -> Int { var count = 0 let maxFD = getdtablesize() for fd in 0..<maxFD { if fcntl(fd, F_GETFD) != -1 { count += 1 } } return count } With this code, we obtained the following data: On a device with iOS 26 Beta 1, 2, or 3: FD LIMIT: soft: 256, hard: 9223372036854775807 Open file descriptors BEFORE Firebase.configure(): 256 On a device with iOS 18: FD LIMIT: soft: 256, hard: 9223372036854775807 Open file descriptors BEFORE Firebase.configure(): 57 In the case of the device running iOS 26 beta, the app crashes when executing Firebase.configure() because it cannot open the plist file, even though it can be found at the correct path — meaning the OS locates it. To confirm this was indeed the issue, we used the following code to close FDs before proceeding with Firebase configuration. By placing a breakpoint just before Firebase.configure() and running the following LLDB command: expr -l c -- for (int fd = 180; fd < 256; fd++) { (int)close(fd); } This released the FDs, allowing Firebase to proceed with its configuration as expected. However, the app would later crash again after hitting the soft limit of file descriptors once more. Digging deeper, we used this code to try to identify which FDs were being opened and causing the soft limit to be exceeded: func checkFDPath() { var r = rlimit() if getrlimit(RLIMIT_NOFILE, &r) == 0 { print("FD LIMIT: soft: \(r.rlim_cur), hard: \(r.rlim_max)") for fd in 0..<Int32(r.rlim_cur) { var path = [CChar](repeating: 0, count: Int(PATH_MAX)) if fcntl(fd, F_GETPATH, &path) != -1 { print(String(cString: path)) } } } } We ran this command at the very beginning of the didFinishLaunching method in the AppDelegate. On iOS 26, the log repeatedly showed Cryptexes creating a massive number of FDs, such as: /dev/null /dev/ttys000 /dev/ttys000 /private/var/mobile/Containers/Data/Application/AEE414F2-7D6F-44DF-A6D9-92EDD1D2B014/Library/Application Support/DTX_8.191.1.1003.sqlite /private/var/mobile/Containers/Data/Application/AEE414F2-7D6F-44DF-A6D9-92EDD1D2B014/Library/Caches/KSCrash/MyAppScheme/Data/ConsoleLog.txt /private/var/mobile/Containers/Data/Application/AEE414F2-7D6F-44DF-A6D9-92EDD1D2B014/Library/HTTPStorages/mybundleId/httpstorages.sqlite /private/var/mobile/Containers/Data/Application/AEE414F2-7D6F-44DF-A6D9-92EDD1D2B014/Library/HTTPStorages/mybundleId/httpstorages.sqlite-wal /private/var/mobile/Containers/Data/Application/AEE414F2-7D6F-44DF-A6D9-92EDD1D2B014/Library/HTTPStorages/mybundleId/httpstorages.sqlite-shm /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.01 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.11 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.12 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.13 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.14 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.15 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.16 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.17 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.18 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.19 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.20 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.21 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.22 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.23 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.24 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.25 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.26 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.29 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.30 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.31 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.32 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.36 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.37 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.38 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.39 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.40 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e … This repeats itself a lot of times. … /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.36 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.37 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.38 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.39 /private/preboot/Cryptexes/OS/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e.40
3
8
316
Jul ’25
Check whether XPC remote proxy responds to selector, without causing exception and connection invalidation?
I have several processes maintaining NSXPConnection to an XPC service. The connections are bi-directional. Each side service and clients) of the connection exports an object, and an XPCInterface. The @protocols are different - to the service, and from the service to clients. So long as all the "clients" fully implement their "call-back" @protocol, there's no problem. All works fine. However - If a client does NOT implement a method in the "call back protocol", or completely neglects to export an object, or interface - and the service attempts to call back using the nonexistent method -- the XPC connection invalidates immediately. So far - expected behaviour. However, if I want the service to behave to the client a little like a "delegate" style -- and check first whether the client "respondsToSelector" or even - supports an interface BEFORE calling it, then this doesn't work. When my XPC service tries the following on a client connection: if (xpcConnection.remoteObjectInterface == nil) os_log_error(myXPCLog, "client has no remote interface); the condition is never met - i.e. the "remoteObjectInterface is never nil even when the client does NOT configure its NSXPCConnection with any incoming NSXPCInterface, and does not set an "exportedObject" Furthermore, the next check: if ([proxy respondsToSelector:@selector(downloadFiltersForCustomer:withReply:)]) { } will not only fail - but will drop the connection. The client side gets the invalidation with the following error: <NSXPCConnection: 0x600000b20000> connection to service with pid 2477 named com.proofpoint.ecd: received an undecodable message for proxy 1 (no exported object to receive message). Dropping message. I guess the "undecidable message" is the respondsToSelector - because the code doesn't get to attempt anything else afterwards, the connection drops. Is there a way to do this check "quietly", or suffering only "interruption", but without losing the connection,
3
0
735
Jan ’25
Background Audio Recording
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?
3
0
142
Apr ’25
can an xpc service access the keychain.
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.
3
0
125
Jul ’25
Using raise in GCD can cause timing issues with the signal mechanism.
when we use raise in GCD, the signal handler is executed asynchronously, whereas in pthread, it is executed synchronously as expected. example: #include &lt;Foundation/Foundation.h&gt; #include &lt;pthread/pthread.h&gt; 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(&amp;action.sa_mask); action.sa_sigaction = &amp;HandleSignal; struct sigaction pre_sa; for(int i = 0; i &lt; fatalSignalsCount; i++) { int sigResult = sigaction(g_fatalSignals[i], &amp;action, &amp;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(&amp;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
4
0
215
Sep ’25