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?
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
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.
Hi, I have been recently debugging the BGContinuedProcessingTask API and encountered some of the following issues. I hope you can provide some answers:
First, let me explain my understanding of this API. I believe its purpose is to allow an app to trigger tasks that can be represented with progress indicators and require a certain amount of time to complete.
After entering the background, these tasks can continue to be completed through the BGContinuedProcessingTask, preventing the system from terminating them before they are finished.
In the launchHandler of the registration process, we only need to do a few things:
Determine whether the actual business processing is still ongoing.
Update the progress, title, and subtitle.
Handle the expirationHandler.
Set the task as completed.
Here are some issues I encountered during my debugging process:
After I called register and submit, the BGContinuedProcessingTask could not be triggered. The return values from my API calls were all normal.
I tried different device models, and some could trigger the task normally, such as the 15 Pro Max and 12 Pro Max. However, there were also some models, such as the 17 Pro, 15 Pro, and 15, that could not trigger the task properly. Moreover, there was no additional error information to help locate the issue.
The background task failed unexpectedly, but my app was still running normally. As I mentioned above, my launchHandler only retrieves the actual business status and updates it.
If a background task fails unexpectedly while the app is still running normally, it can mislead users and degrade the user experience of the app.
Others have also mentioned the issue of inconsistent behavior on devices that do not support Dynamic Island. On devices that support Dynamic Island,
when a task is triggered in the foreground, the app does not immediately display a pop-up notification within the app. However, on devices that do not support Dynamic Island,
the app directly displays a pop-up notification within the app, and this notification does not disappear when switching between different screens within the same app.
The user needs to actively swipe up to dismiss it. I think this experience is too intrusive for users. I would like to know whether this will be maintained in the future or if there is a plan to fix it.
On devices that do not support Dynamic Island, using the beta version 26.1 of the system,
if the system is in dark mode but the app triggers a business interface in white, the pop-up notification will have the same color as the current page, making it difficult to read the content inside the pop-up.
Users can actively stop background tasks by using the stop button, or the system can also stop tasks automatically when resources are insufficient or when a task is abnormal.
However, according to the current API, all these actions are triggered through the expirationHandler.
Currently, there is no way to distinguish whether the task was stopped by the user, by the system due to resource insufficiency, or due to an abnormal task.
I would like to know whether there will be more information provided in the future to help distinguish these different scenarios.
I believe that the user experience issues mentioned in points 2 and 3 are the most important. Please help to answer the questions and concerns above. Thank you!
I've adopted the new BGContinuedProcessingTask in iOS 26, and it has mostly been working well in internal testing. However, in production I'm getting reports of the tasks failing when the app is put into the background.
A bit of info on what I'm doing: I need to download a large amount of data (around 250 files) and process these files as they come down. The size of the files can vary: for some tasks each file might be around 10MB. For other tasks, the files might be 40MB. The processing is relatively lightweight, but the volume of data means the task can potentially take over an hour on slower internet connections (up to 10GB of data).
I set the totalUnitCount based on the number of files to be downloaded, and I increment completedUnitCount each time a file is completed.
After some experimentation, I've found that smaller tasks (e.g. 3GB, 10MB per file) seem to be okay, but larger tasks (e.g. 10GB, 40MB per file) seem to fail, usually just a few seconds after the task is backgrounded (and without even opening any other apps). I think I've even observed a case where the task expired while the app was foregrounded!
I'm trying to understand what the rules are with BGContinuedProcessingTask and I can see at least four possibilities that might be relevant:
Is it necessary to provide progress updates at some minimum rate? For my larger tasks, where each file is ~40MB, there might be 20 or 30 seconds between progress updates. Does this make it more likely that the task will be expired?
For larger tasks, the total time to complete can be 60–90 mins on slower internet connections. Is there some maximum amount of time the task can run for? Does the system attempt some kind of estimate of the overall time to complete and expire the task on that basis?
The processing on each file is relatively lightweight, so most of the time the async stream is awaiting the next file to come down. Does the OS monitor the intensity of workload and suspend the task if it appears to be idle?
I've noticed that the task UI sometimes displays a message, something along the lines of "Do you want to continue this task?" with a "Continue" and "Stop" option. What happens if the user simply ignores or doesn't see this message? Even if I tap "Continue" the task still seems to fail sometimes.
I've read the docs and watched the WWDC video, but there's not a whole lot of information on the specific issues I mention above. It would be great to get some clarity on this, and I'd also appreciate any advice on alternative ways I could approach my specific use case.
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!
Topic:
App & System Services
SubTopic:
Processes & Concurrency
I’m looking for an authoritative answer on how BGAppRefreshTask behaves after a user force-quits an app (swipes it away in the App Switcher).
My app relies on early-morning background refresh to prepare and schedule notifications based on user-defined thresholds and weather forecasts.
Behavior across devices seems inconsistent, however: sometimes a scheduled background refresh still runs, and other times it appears completely blocked.
Apple’s documentation doesn’t clearly state what should happen, and developer discussions conflict.
Could someone from Apple please clarify:
Will a previously scheduled BGAppRefreshTask run after the user force-quits the app?
If not, is there a recommended alternative for time-sensitive updates that must schedule user alerts?
What is the expected system behavior regarding the predictability of background refresh after a force-quit?
A definitive answer would help ensure the app aligns with intended system behavior.
Thanks!
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 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?
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!
MacOS Version: 14.7.2
macOS SDKs:
macOS 14.5 -sdk macosx14.5
I am working on a sample program for validation Against:
Team Identifier
Developer ID
I started with validating Team Identifier, but my validation is not working and it is allowing to launch programs which are not matching the team identifier in the signature.
Below is my code:
func verifyExecutableWithLCR(executablePath: String, arguments: [String]) -> Bool {
let task = Process()
task.launchPath = executablePath
task.arguments = arguments
if #available(macOS 14.4, *) {
print("launchRequirementData is available on this system.")
do {
let req = try OnDiskCodeRequirement.allOf {
TeamIdentifier("ABCDEFGHI")
//SigningIdentifier("com.***.client.***-Client.****")
}
let encoder = PropertyListEncoder()
encoder.outputFormat = .xml
let requirementData = try encoder.encode(req)
task.launchRequirementData = requirementData
print("launchRequirementData is set.")
try task.run()
print("[SUCCESS] Executable passed the code signature verification.")
return true
} catch {
print("[ERROR] Code signature verification failed: \(error.localizedDescription)")
return false
}
} else {
print("[WARNING] launchRequirement is not available on this macOS version.")
return false
}
}
Could you please help me in identifying whay am I doing wrong here?
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.
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!.
We're developing an Electron app for MacOS App Store. When updating our app through TestFlight, TestFlight prompts "Close This App to Update", and when I click "Continue" our app would be "Terminated" for update.
Now this is where things go wrong. On MacOS 15 our app seems to be gracefully terminating (We attached it with lldb and it shows that our app returns with 0 when we click "Continue") which is fine.
However for MacOS 26 though, it seems that TestFlight just directly SIGKILLs our app (indicated by lldb), which means that all of our app's child processes are left orphaned. Even worse, our app is singleton, which means that when the app relaunches it fails, because the leftover child processes from the previously SIGKILLed session is still alive, and even if we want to kill those orphaned child processes we can't because our app is sandboxed thus cannot kill processes outside of the current sandbox.
We captured output from log stream (app name redacted):
12-02 22:08:16.477036-0800 0x5452 Default 0x5a4a7 677 7 installcoordinationd: [com.apple.installcoordination:daemon] -[IXSCoordinatorProgress setTotalUnitsCompleted:]: Progress for coordinator: [com.our.app/Invalid/[user-defined//Applications/OurApp.app]], Phase: IXCoordinatorProgressPhaseLoading, Percentage: 99.454 123: Attempt to set units completed on finished progress: 214095161 2025-12-02 22:08:16.483056-0800 0x53ba Default 0x5a5c9 167 0 runningboardd: (RunningBoard) [com.apple.runningboard:connection] Received termination request from [osservice<com.apple.installcoordinationd(274)>:677] on <RBSProcessPredicate <RBSProcessBundleIdentifierPredicate "com.our.app">> with context <RBSTerminateContext| explanation:installcoordinationd app:[com.our.app/Invalid/[user-defined//Applications/OurApp.app]] uuid:A3BC0629-124E-4165-ABB7-1324380FC354 isPlaceholder:N re portType:None maxTerminationResistance:Absolute attrs:[ 2025-12-02 22:08:16.488651-0800 0x53ba Default 0x5a5c9 167 7 runningboardd: (RunningBoard) [com.apple.runningboard:ttl] Acquiring assertion targeting system from originator [osservice<com.apple.installcoordinationd(274)>:677] with description <RBSAssertionDescriptor| "installcoordinationd app:[com.our.app/Invalid/[user-defined//Applications/OurApp.app]] uuid:A3BC0629-124E-4165-ABB7-1324380FC354 isPlaceholder:N" ID:167-677-1463 target:system attributes:[ 2025-12-02 22:08:16.489353-0800 0x53ba Default 0x5a5c9 167 0 runningboardd: (RunningBoard) [com.apple.runningboard:process] [app<application.com.our.app.485547.485561(501)>:2470] Terminating with context: <RBSTerminateContext| explanation:installcoordinationd app:[com.our.app/Invalid/[user-defined//Applications/OurApp.app]] uuid:A3BC0629-124E-4165-ABB7-1324380FC354 isPlaceholder:N reportType:None maxTerminationResistance:Absolute attrs:[ 2025-12-02 22:10:23.920869-0800 0x5a5a Default 0x5a4c6 674 14 appstoreagent: [com.apple.appstored:Library] [A95D57D7] Completed with 1 result: <ASDApp: 0xc932a8780>: {bundleID = com.our.app; completedUnitCount = 600; path = /Applications/OurApp.app; installed = 0} 2025-12-02 22:10:32.027304-0800 0x5ae5 Default 0x5a4c7 674 14 appstoreagent: [com.apple.appstored:Library] [BEB5F2FD] Completed with 1 result: <ASDApp: 0xc932a8780>: {bundleID = com.our.app; completedUnitCount = 600; path = /Applications/OurApp.app; installed = 0} 2025-12-02 22:10:36.542321-0800 0x5b81 Default 0x5a4c8 674 14 appstoreagent: [com.apple.appstored:Library] [185B9DD6] Completed with 1 result: <ASDApp: 0xc932a8780>: {bundleID = com.our.app; completedUnitCount = 600; path = /Applications/OurApp.app; installed = 0}
The line "Terminating with context" seems suspicious. This line is not seen on MacOS 15, only MacOS 26. Is this documented behavior? If so, how can we handle this?
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
App Store
Mac App Store
TestFlight
I have been experimenting with the BGContinuedProcessingTask API recently (and published sample code for it https://github.com/infinitepower18/BGContinuedProcessingTaskDemo)
I have noticed that if I lock the phone, the code that runs as part of the task stops executing. My sample code simply updates the progress each second until it gets to 100, so it should be completed in 1 minute 40 seconds. However, after locking the phone and checking the lock screen a few seconds later the progress indicator was in the same position as before I locked it.
If I leave the phone locked for several minutes and check the lock screen the live activity says "Task failed".
I haven't seen anything in the documentation regarding execution of tasks while the phone is locked. So I'm a bit confused if I encountered an iOS bug here?
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]).
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
}
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?
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
Foundation
Inter-process communication
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?
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
Files and Storage
App Sandbox
XPC
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
<>
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.