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

Processes & Concurrency Resources
General: DevForums subtopic: App & System Services > Processes & Concurrency Processes & concurrency covers a number of different technologies: Background Tasks Resources Concurrency Resources — This includes Swift concurrency. Service Management Resources XPC Resources Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com"
0
0
145
Jul ’25
BGTaskScheduler crashes on iOS 18.4
I've been seeing a high number of BGTaskScheduler related crashes, all of them coming from iOS 18.4. I've encountered this myself once on launch upon installing my app, but haven't been able to reproduce it since, even after doing multiple relaunches and reinstalls. Crash report attached at the bottom of this post. I am not even able to symbolicate the reports despite having the archive on my MacBook: Does anyone know if this is an iOS 18.4 bug or am I doing something wrong when scheduling the task? Below is my code for scheduling the background task on the view that appears when my app launches: .onChange(of: scenePhase) { newPhase in if newPhase == .active { #if !os(macOS) let request = BGAppRefreshTaskRequest(identifier: "notifications") request.earliestBeginDate = Calendar.current.date(byAdding: .hour, value: 3, to: Date()) do { try BGTaskScheduler.shared.submit(request) Logger.notifications.log("Background task scheduled. Earliest begin date: \(request.earliestBeginDate?.description ?? "nil", privacy: .public)") } catch let error { // print("Scheduling Error \(error.localizedDescription)") Logger.notifications.error("Error scheduling background task: \(error.localizedDescription, privacy: .public)") } #endif ... } 2025-02-23_19-53-50.2294_+0000-876d2b8ec083447af883961da90398f00562f781.crash
33
8
3.6k
Apr ’25
Background App Refresh
Hi, I have a couple questions about background app refresh. First, is the function RefreshAppContentsOperation() where to implement code that needs to be run in the background? Second, despite importing BackgroundTasks, I am getting the error "cannot find operationQueue in scope". What can I do to resolve that? Thank you. func scheduleAppRefresh() { let request = BGAppRefreshTaskRequest(identifier: "peaceofmindmentalhealth.RoutineRefresh") // Fetch no earlier than 15 minutes from now. request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60) do { try BGTaskScheduler.shared.submit(request) } catch { print("Could not schedule app refresh: \(error)") } } func handleAppRefresh(task: BGAppRefreshTask) { // Schedule a new refresh task. scheduleAppRefresh() // Create an operation that performs the main part of the background task. let operation = RefreshAppContentsOperation() // Provide the background task with an expiration handler that cancels the operation. task.expirationHandler = { operation.cancel() } // Inform the system that the background task is complete // when the operation completes. operation.completionBlock = { task.setTaskCompleted(success: !operation.isCancelled) } // Start the operation. operationQueue.addOperation(operation) } func RefreshAppContentsOperation() -> Operation { }
23
0
473
Oct ’25
Some fundamental doubts about DisptachQueue and GCD
I understand that GCD and it's underlying implementations have evolved over time. And many things have not been shared explicitly in Apple documentation. The most concepts of DispatchQueue (serial and concurrent queues), DispatchQoS, target queue and system provided queues: main and globals etc. I have some doubts & questions to clarify: [Main Dispatch Queue] [Link] Because the main queue doesn't behave entirely like a regular serial queue, it may have unwanted side-effects when used in processes that are not UI apps (daemons). For such processes, the main queue should be avoided. What does it mean? Can you elaborate? [Global Concurrent Dispatch Queues] Are they global to a process or across processes on a device. I believe it is the first case but just wanted to be sure. [Global Concurrent Dispatch Queues] Does system create 4 (for each QoS) * 2 (over-commiting and non-overcommiting queues) = 8 queues in all. When does which type of queue comes into play? [Custom Queue][Target Queue concept] [swift-corelibs-libdispatch/man/dispatch_queue_create.3] QUOTE The default target queue of all dispatch objects created by the application is the default priority global concurrent queue. UNQUOTE Is this stil true? We could not find a mention of this in any latest official apple documentation (though some old forum threads (one more) and github code documentation indicate the same). The official documentation only says: [dispatch_set_target_queue] QUOTE If you want the system to provide a queue that is appropriate for the current object UNQUOTE [dispatch_queue_create_with_target] QUOTE Specify DISPATCH_TARGET_QUEUE_DEFAULT to set the target queue to the default type for the current dispatch queue.UNQUOTE [Dispatch>DispatchQueue>init] QUOTE Specify DISPATCH_TARGET_QUEUE_DEFAULT if you want the system to provide a queue that is appropriate for the current object. UNQUOTE What is the difference between passing target queue as 'nil' vs 'DISPATCH_TARGET_QUEUE_DEFAULT' to DispatchQueue init? [Custom Queue][Target Queue concept] [dispatch_set_target_queue] QUOTE The system doesn't allocate threads to the dispatch queue if it has a target queue, unless that target queue is a global concurrent queue. UNQUOTE The system does allocate threads to the custom dispatch queues that have global concurrent queue as the default target. What does that mean? Why does targetting to global concurrent queues mean in that case? [System / GCD Thread Pool] that excutes work items from DispatchQueue: Is this thread pool per queue? or across queues per process? or across processes per device?
14
0
1.2k
Feb ’25
What DispatchQueues should i use for my app's communication subsystem?
We would be creating N NWListener objects and M NWConnection objects in our process' communication subsystem to create server sockets, accepted client sockets on server and client sockets on clients. Both NWConnection and NWListener rely on DispatchQueue to deliver state changes, incoming connections, send/recv completions etc. What DispatchQueues should I use and why? Global Concurrent Dispatch Queue (and which QoS?) for all NWConnection and NWListener One custom concurrent queue (which QoS?) for all NWConnection and NWListener? (Does that anyways get targetted to one of the global queues?) One custom concurrent queue per NWConnection and NWListener though all targetted to Global Concurrent Dispatch Queue (and which QoS?)? One custom concurrent queue per NWConnection and NWListener though all targetted to single target custom concurrent queue? For every option above, how am I impacted in terms of parallelism, concurrency, throughput & latency and how is overall system impacted (with other processes also running)? Seperate questions (sorry for the digression): Are global concurrent queues specific to a process or shared across all processes on a device? Can I safely use setSpecific on global dispatch queues in our app?
13
0
942
Jan ’25
Service Showing "Not Responding" in Activity Monitor Despite Running Threads.
I am encountering an issue with my application, BloxOneEndpoint.pkg, which includes two services: rc_service_infoblox – Runs as the root user. Controller Application – Runs as a normal user. Although a thread within rc_service_infoblox is running fine and performing its expected tasks, I notice that the service appears as "Not Responding" in Activity Monitor. Despite normal functionality, this status is concerning, as it may indicate some issue to customer. I would appreciate any insights into why this might be happening and how to resolve it. Is there a specific API or mechanism I should use to ensure the service remains in a "Running" state in Activity Monitor? Thank you for your guidance.
13
0
189
Apr ’25
Termination due to Exceed Port Limit
Hi, I have received the following report after app termination. I have researched online but cannot determine the root cause. Any tips or ideas would help please. Could it be Location Services, UserNotification Services, or Network Requests? Thank you, Brendan Translated Report (Full Report Below) Incident Identifier: 6CD59A17-15B1-4F4E-AE84-0286F22893A4 CrashReporter Key: 3d12fb7359053239708afd24c7eed0267a9cc601 Hardware Model: iPhone13,3 Process: AnchorNet3 [5605] Path: /private/var/containers/Bundle/Application/5EA7F893-D562-45B8-8995-5EAB15F85A7E/AnchorNet3.app/AnchorNet3 Identifier: com.sailsecrets.AnchorNet3 Version: 3.17 (3.17) Code Type: ARM-64 (Native) Role: Foreground Parent Process: launchd [1] Coalition: com.sailsecrets.AnchorNet3 [1443] Date/Time: 2025-02-06 00:12:03.6136 +0100 Launch Time: 2025-02-05 22:11:19.4220 +0100 OS Version: iPhone OS 18.2 (22C5131e) Release Type: Beta Baseband Version: 5.20.03 Report Version: 104 Exception Type: EXC_RESOURCE (SIGKILL) Exception Codes: 0x0000000000020000, 0x0000000000000000 Termination Reason: PORT_SPACE 14123288431434006528 (Limit 131072 ports) Exceeded system-wide per-process Port Limit Triggered by Thread: 3 Thread 0 name: Dispatch queue: com.apple.main-thread Thread 0: 0 libsystem_kernel.dylib 0x1e27414e4 kevent_id + 8 1 libdispatch.dylib 0x198f51b40 _dispatch_kq_poll + 228 2 libdispatch.dylib 0x198f51080 _dispatch_event_loop_poke + 340 3 QuartzCore 0x192d4631c CA::Context::commit_transaction(CA::Transaction*, double, double*) + 17164 4 QuartzCore 0x192cb8d58 CA::Transaction::commit() + 648 5 QuartzCore 0x192cb8764 CA::Transaction::flush_as_runloop_observer(bool) + 88 6 UIKitCore 0x193a3fd14 _UIApplicationFlushCATransaction + 52 7 UIKitCore 0x193a3d1e0 __setupUpdateSequence_block_invoke_2 + 332 8 UIKitCore 0x193a3d054 UIUpdateSequenceRun + 84 9 UIKitCore 0x193a3f984 schedulerStepScheduledMainSection + 172 10 UIKitCore 0x193a3d5a0 runloopSourceCallback + 92 11 CoreFoundation 0x1911f1f3c CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 28 12 CoreFoundation 0x1911f1ed0 __CFRunLoopDoSource0 + 176 13 CoreFoundation 0x1911f4b30 __CFRunLoopDoSources0 + 244 14 CoreFoundation 0x1911f3d2c __CFRunLoopRun + 840 15 CoreFoundation 0x191246274 CFRunLoopRunSpecific + 588 16 GraphicsServices 0x1de34d4c0 GSEventRunModal + 164 17 UIKitCore 0x193d8f480 -[UIApplication run] + 816 18 UIKitCore 0x1939b5410 UIApplicationMain + 340 19 SwiftUI 0x195b43e30 closure #1 in KitRendererCommon(:) + 168 20 SwiftUI 0x195b43d60 runApp(:) + 100 21 SwiftUI 0x195b43c44 static App.main() + 180 22 AnchorNet3.debug.dylib 0x1025e97bc static MainApp.$main() + 40 23 AnchorNet3.debug.dylib 0x1025eaacc __debug_main_executable_dylib_entry_point + 12 24 dyld 0x1b7352de8 start + 2724 Thread 1 name: com.apple.CoreMotion.MotionThread Thread 1: 0 libsystem_kernel.dylib 0x1e2741788 mach_msg2_trap + 8 1 libsystem_kernel.dylib 0x1e2744e98 mach_msg2_internal + 80 2 libsystem_kernel.dylib 0x1e2744db0 mach_msg_overwrite + 424 3 libsystem_kernel.dylib 0x1e2744bfc mach_msg + 24 4 CoreFoundation 0x1911f47f4 __CFRunLoopServiceMachPort + 160 5 CoreFoundation 0x1911f3ea0 __CFRunLoopRun + 1212 6 CoreFoundation 0x191246274 CFRunLoopRunSpecific + 588 7 CoreFoundation 0x191259814 CFRunLoopRun + 64 8 CoreMotion 0x19e89cc5c 0x19e88d000 + 64604 9 libsystem_pthread.dylib 0x21bcfb7d0 _pthread_start + 136 10 libsystem_pthread.dylib 0x21bcfb480 thread_start + 8 Thread 2 name: com.apple.uikit.eventfetch-thread Thread 2: 0 libsystem_kernel.dylib 0x1e2741788 mach_msg2_trap + 8 1 libsystem_kernel.dylib 0x1e2744e98 mach_msg2_internal + 80 2 libsystem_kernel.dylib 0x1e2744db0 mach_msg_overwrite + 424 3 libsystem_kernel.dylib 0x1e2744bfc mach_msg + 24 4 CoreFoundation 0x1911f47f4 __CFRunLoopServiceMachPort + 160 5 CoreFoundation 0x1911f3ea0 __CFRunLoopRun + 1212 6 CoreFoundation 0x191246274 CFRunLoopRunSpecific + 588 7 Foundation 0x18fdc8338 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212 8 Foundation 0x18ff24e24 -[NSRunLoop(NSRunLoop) runUntilDate:] + 64 9 UIKitCore 0x193e22a74 -[UIEventFetcher threadMain] + 420 10 Foundation 0x18feb4194 NSThread__start + 724 11 libsystem_pthread.dylib 0x21bcfb7d0 _pthread_start + 136 12 libsystem_pthread.dylib 0x21bcfb480 thread_start + 8 Thread 3 name: com.apple.SwiftUI.AsyncRenderer Thread 3 Crashed: 0 libsystem_kernel.dylib 0x1e274162c _kernelrpc_mach_port_allocate_trap + 8 1 libsystem_kernel.dylib 0x1e2748478 mach_port_allocate + 36 2 QuartzCore 0x192d4552c CA::Context::commit_transaction(CA::Transaction*, double, double*) + 13596 3 QuartzCore 0x192cb8d58 CA::Transaction::commit() + 648 4 QuartzCore 0x192cb8764 CA::Transaction::flush_as_runloop_observer(bool) + 88 5 CoreFoundation 0x19119f894 CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 36 6 CoreFoundation 0x19119f3e8 __CFRunLoopDoObservers + 552 7 CoreFoundation 0x1912462c0 CFRunLoopRunSpecific + 664 8 Foundation 0x18fdc8338 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212 9 Foundation 0x18fdc4500 -[NSRunLoop(NSRunLoop) run] + 64 10 SwiftUI 0x195c276d8 specialized static DisplayLink.asyncThread(arg:) + 792 11 SwiftUI 0x195c273a8 @objc static DisplayLink.asyncThread(arg:) + 72 <>
11
0
587
Feb ’25
SMAppService Sample Code seems broken
I abandoned Mac development back around 10.4 when I departed Apple and am playing catch-up, trying to figure out how to register a privileged helper tool that can execute commands as root in the new world order. I am developing on 13.1 and since some of these APIs debuted in 13, I'm wondering if that's ultimately the root of my problem. Starting off with the example code provided here: https://developer.apple.com/documentation/servicemanagement/updating-your-app-package-installer-to-use-the-new-service-management-api Following all build/run instructions in the README to the letter, I've not been successful in getting any part of it to work as documented. When I invoke the register command the test app briefly appears in System Settings for me to enable, but once I slide the switch over, it disappears. Subsequent attempts to invoke the register command are met only with the error message: `Unable to register Error Domain=SMAppServiceErrorDomain Code=1 "Operation not permitted" UserInfo={NSLocalizedFailureReason=Operation not permitted} The app does not re-appear in System Settings on these subsequent invocations. When I invoke the status command the result mysteriously equates to SMAppService.Status.notFound. The plist is in the right place with the right name and it is using the BundleProgram key exactly as supplied in the sample code project. The executable is also in the right place at Contents/Resources/SampleLaunchAgent relative to the app root. The error messaging here is extremely disappointing and I'm not seeing any way for me to dig any further without access to the underlying Objective-C (which the Swift header docs reference almost exclusively, making it fairly clear that this was a... Swift... Port... [Pun intended]).
10
0
235
Sep ’25
Getting Progress from long running process
I have been working on updating an old app that makes extensive use of Objective-C's NSTask. Now using Process in Swift, I'm trying to gather updates as the process runs, using readabilityHandler and availableData. However, my process tends to exit before all data has been read. I found this post entitled "Running a Child Process with Standard Input and Output" but it doesn't seem to address gathering output from long-running tasks. Is there a straightforward way to gather ongoing output from a long running task without it prematurely exiting?
10
0
155
May ’25
Cross process URL bookmark
I am developing a background application that acts as a metadata server under MacOS written in Swift. Sandboxed clients prompt the user to select URLs which are passed to the server as security scoped bookmarks via an App Group and the metadata will be passed back. I don't want the I/O overhead of passing the complete image file data to the server. All the variations I have tried of creating security scoped bookmarks in the client and reading them from the server fail with error messages such as "The file couldn’t be opened because it isn’t in the correct format." Can anyone guide me in the right direction or is this just not possible?
10
0
174
Jun ’25
How is BGContinuedProcessingTask intended to be used?
Hello, I'm trying to adopt the new BGContinuedProcessingTask API, but I'm having a little trouble imagining how the API authors intended it be used. I saw the WWDC talk, but it lacked higher-level details about how to integrate this API, and I can't find a sample project. I notice that we can list wildcard background task identifiers in our Info.plist files now, and it appears this is to be used with continued tasks - a user might start one video encoding, then while it is ongoing, enqueue another one from the same app, and these tasks would have identifiers such as "MyApp.VideoEncoding.ABCD" and "MyApp.VideoEncoding.EFGH" to distinguish them. When it comes to implementing this, is the expectation that we: a) Register a single handler for the wildcard pattern, which then figures out how to fulfil each request from the identifier of the passed-in task instance? Or b) Register a unique handler for each instance of the wildcard pattern? Since you can't unregister handlers, any resources captured by the handler would be leaked, so you'd need to make sure you only register immediately before submission - in other words register + submit should always be called as a pair. Of course, I'd like to design my application to use this API as the authors intended it be used, but I'm just not entirely sure what that is. When I try to register a single handler for a wildcard pattern, the system rejects it at runtime (while allowing registrations for each instance of the pattern, indicating that at least my Info.plist is configured correctly). That points towards option B. If it is option B, it's potentially worth calling that out in documentation - or even better, perhaps introduce a new call just for BGContinuedProcessingTask instead of the separate register + submit calls? Thanks for your insight. K Aside: Also, it would be really nice if the handler closure would be async. Currently if you need to await on something, you need to launch an unstructured Task, but that causes issues since BGContinuedProcessingTask is not Sendable, so you can't pass it in to that Task to do things like update the title or mark the BGTask as complete.
9
0
321
3w
BGAppRefreshTask expires after few seconds (2-5 seconds).
I can see a number of events in our error logging service where we track expired BGAppRefreshTask. We use BGAppRefreshTask to update metadata. By looking into those events I can see most of reported expired tasks expired around 2-5 seconds after the app was launched. The documentations says: The system decides the best time to launch your background task, and provides your app up to 30 seconds of background runtime. I expected "up to 30 seconds" to be 10-30 seconds range, not that extremely short. Is there any heuristic that affects how much time the app gets? Is there a way to tell if the app was launched due to the background refresh task? If we have this information we can optimize what the app does during those 5 seconds. Thank you!.
8
0
160
Apr ’25
BGContinuedProcessingTask launchHandler invocation
I'm trying to understand how the API works to perform a function that can continue running if the user closes the app. For a very simple example, consider a function that increments a number on screen every second, counting from 1 to 100, reaching completion at 100. The user can stay in the app for 100s watching it work to completion, or the user can close the app say after 2s and do other things while watching it work to completion in the Live Activity. To do this when the user taps a Start Counting button, you'd 1 Call BGTaskScheduler.shared.register(forTaskWithIdentifier:using:launchHandler:). Question 1: Do I understand correctly, all of the logic to perform this counting operation would exist entirely in the launchHandler block (noting you could call another function you define passing it the task to be able to update its progress)? I am confused because the documentation states "The system runs the block of code for the launch handler when it launches the app in the background." but the app is already open in the foreground. This made me think this block is not going to be invoked until the user closes the app to inform you it's okay to continue processing in the background, but how would you know where to pick up. I want to confirm my thinking was wrong, that all the logic should be in this block from start to completion of the operation, and it's fine even if the app stays in the foreground the whole time. 2 Then you'd create a BGContinuedProcessingTaskRequest and set request.strategy = .fail for this example because you need it to start immediately per the user's explicit tap on the Start Counting button. 3 Call BGTaskScheduler.shared.submit(request). Question 2: If the submit function throws an error, should you handle it by just performing the counting operation logic (call your function without passing a task)? I understand this can happen if for some reason the system couldn't immediately run it, like if there's already too many pending task requests. Seems you should not show an error message to the user, should still perform the request and just not support background continued processing for it (and perhaps consider showing a light warning "this operation can't be continued in the background so keep the app open"). Or should you still queue it up even though the user wants to start counting now? That leads to my next question Question 3: In what scenario would you not want the operation to start immediately (the queue behavior which is the default), given the app is already in the foreground and the user requested some operation? I'm struggling to think of an example, like a button titled Compress Photos Whenever You Can, and it may start immediately or maybe it won't? While waiting for the launchHandler to be invoked, should the UI just show 0% progress or "Pending" until the system can get to this task in the queue? Struggling to understand the use cases here, why make the user wait to start processing when they might not even intend to close the app during the operation? Thanks for any insights! As an aside, a sample project with a couple use cases would have been incredibly helpful to understand how the API is expected to be used.
8
0
260
Oct ’25
macOS 26: Menu bar icon not showing for Python app running PySide6
Since macOS 26, including the latest 26.1, the menu bar icon does not show up for our app called Plover which is built with PySide6 (based on Qt 6) and runs via a relocatable python that is packaged into the app. The code is open source and can be found on GitHub. The latest release, including the notarized DMG, can be found here. When running the .app via the command below, the menu bar icon does show up but the process that is running is python3.13 and not Plover: /Applications/Plover.app/Contents/MacOS/Plover -l debug When running the app by just clicking on the application icon, the process is Plover but the menu bar icon is not showing - also not in the settings (Menu Bar > Allow in the Menu Bar). Before macOS 26, the menu bar icon was always shown. Some pointers to potentially relevant parts of our code: shell script that builds the .app Info.plist plover_launcher.c trayicon.py This problem might be related to this thread, including the discussion around Qt not calling NSApplicationMain. What I'm trying to figure out is whether this is a problem with macOS 26, Qt 6, PySide6, or our code. Any pointers are highly appreciated!
7
0
251
1w
XPC Service Cleanup and Freeing Memory
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 ?
7
0
483
Mar ’25
Control status item and login item from within app
In macOS 26 I noticed there is a section Menu Bar in System Settings which allows to toggle visibility of status items created with NSStatusItem. I'm assuming this is new, since I never noticed it before. Currently my app has a menu item that allows toggling its status item, but now I wonder whether it should always create the status item and let the user control its visibility from System Settings. Theoretically, keeping this option inside the app could lead to confusion if the user has previously disabled the status item in System Settings, then perhaps forgot about it, and then tries to enable it inside the app, but apparently nothing happens because System Settings overrides the app setting. Should I remove the option inside the app? This also makes me think of login items, which can be managed both in System Settings and inside the app via SMAppService. Some users ask why my app doesn't have a launch at login option, and I tell them that System Settings already offers that functionality. Since there is SMAppService I could offer an option inside the app that is kept in sync with System Settings, but I prefer to avoid duplicating functionality, particularly if it's something that is changed once by the user and then rarely (if ever) changed afterwards. But I wonder: why can login items be controlled by an app, and the status item cannot (at least I'm not aware of an API that allows to change the option in System Settings)? If the status item can be overridden in System Settings, why do login items behave differently?
7
0
147
Sep ’25
How can I bundle resources along with my launch agent?
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?
7
0
146
Jun ’25
BGContinuedProcessingTask what's the point?
Hi, This post is coming from frustration of working on using BGContinuedProcessingTask for almost 2 weeks, trying to get it to actually complete in the background after the app is backgrounded. My process will randomlly finish and not finish and have no idea why. I'm properly using and setting task?.progress.totalUnitCount = [some number] task?.progress.completedUnitCount = [increment as processed] I know this, because it all looks propler as long as the app insn't backgrounded. So it's not a progress issue. The task will ALWAYS complete. The device has full power, as it is plugged in as I run from within Xcode. So, it's not a power issue. Yes, the process will take a few minutes, but I thought that is BGContinuedProcessingTask purpose in iOS 26. For long running process that a user could place in the background and leave the app, assuming the process would actually finish. Why bother introducing a feature that only works with short tasks that don't actually need long running time in the first place.
7
0
157
4w
iOS BGTaskScheduler
Hi! I'm trying to submit a task request into BGTaskScheduler when I background my app. The backgrounding triggers an update of data to a shared app groups container. I'm currently getting the following error and unsure where it's coming from: *** Assertion failure in -[BGTaskScheduler _unsafe_submitTaskRequest:error:], BGTaskScheduler.m:274 Here is my code: BGAppRefreshTaskRequest *request = [[BGAppRefreshTaskRequest alloc] initWithIdentifier:kRBBackgroundTaskIdentifier]; NSError *error = nil; bool success = [[BGTaskScheduler sharedScheduler] submitTaskRequest:request error:&error];
7
0
140
Apr ’25
How to correctly deploy bundled launchdaemons/launchagents?
I'm working on an enterprise product that's mainly a daemon (with Endpoint Security) without any GUI component. I'm looking into the update process for daemons/agents that was introduced with Ventura (Link), but I have to say that the entire process is just deeply unfun. Really can't stress this enough how unfun. Anyway... The product bundle now contains a dedicated Swift executable that calls SMAppService.register for both the daemon and agent. It registers the app in the system preferences login items menu, but I also get an error. Error registering daemon: Error Domain=SMAppServiceErrorDomain Code=1 "Operation not permitted" UserInfo={NSLocalizedFailureReason=Operation not permitted} What could be the reason? I wouldn't need to activate the items, I just need them to be added to the list, so that I can control them via launchctl. Which leads me to my next question, how can I control bundled daemons/agents via launchctl? I tried to use launchctl enable and bootstrap, just like I do with daemons under /Library/LaunchDaemons, but all I get is sudo launchctl enable system/com.identifier.daemon sudo launchctl bootstrap /Path/to/daemon/launchdplist/inside/bundle/Library/LaunchDaemons/com.blub.plist Bootstrap failed: 5: Input/output error (not super helpful error message) I'm really frustrated by the complexity of this process and all of its pitfalls.
7
0
800
Aug ’25
BGContinuedProcessingTask register block not called, submit does not throw an error
I implemented BGContinuedProcessingTask in my app and it seems to be working well for everyone except one user (so far) who has reached out to report nothing happens when they tap the Start Processing button. They have an iPhone 12 Pro Max running iOS 26.1. Restarting iPhone does not fix it. When they turn off the background processing feature in the app, it works. In that case my code directly calls the function to start processing instead of waiting for it to be invoked in the register block (or submit catch block). Is this a bug that's possible to occur, maybe device specific? Or have I done something wrong in the implementation? func startProcessingTapped(_ sender: UIButton) { if isBackgroundProcessingEnabled { startBackgroundContinuedProcessing() } else { startProcessing(backgroundTask: nil) } } func startBackgroundContinuedProcessing() { BGTaskScheduler.shared.register(forTaskWithIdentifier: taskIdentifier, using: .main) { @Sendable [weak self] task in guard self != nil else { return } startProcessing(backgroundTask: task as? BGContinuedProcessingTask) } let request = BGContinuedProcessingTaskRequest(identifier: taskIdentifier, title: title, subtitle: subtitle) request.strategy = .fail if BGTaskScheduler.supportedResources.contains(.gpu) { request.requiredResources = .gpu } do { try BGTaskScheduler.shared.submit(request) } catch { startProcessing(backgroundTask: nil) } } func startProcessing(backgroundTask: BGContinuedProcessingTask?) { // FIXME: Never called for this user when isBackgroundProcessingEnabled is true }
7
0
131
6d