For example, let’s propose an XPC service that can connect to websites. Suppose that I want to connect to Apple.com, microsoft.com, and ibm.com. Can 3 service objects be made between the service and client? Or does the service have to return an ID for each web connection, with the client needing to specify which connection ID along with a command?
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
Just trying to understand the documentation.
Obviously, we can send a request to the service to return all the data at once. Can the data arrive in pieces, involving either multiple async callbacks or a Combine Publisher?
iOS BGProcessingTask + Background Upload Not Executing Reliably on TestFlight (Works in Debug)
Description:
We are facing an issue with BGTaskScheduler and BGProcessingTask when trying to perform a background audio-upload flow on iOS. The behavior is inconsistent between Debug builds and TestFlight (Release) builds.
Summary of the Problem
Our application records long audio files (up to 1 hour) and triggers a background upload using:
BGTaskScheduler
BGProcessingTaskRequest
Background URLSession (background with identifier)
URLSession background upload task + AppDelegate.handleEventsForBackgroundURLSession
In Debug mode (Xcode → Run on device), everything works as expected:
BGProcessingTask executes
handleEventsForBackgroundURLSession fires
Background URLSession continues uploads reliably
Long audio files successfully upload even when the app is in background or terminated
However, in TestFlight / Release mode, the system does not reliably launch the BGProcessingTask or Background URLSession events.
Technical Details
We explicitly register BGTaskScheduler:
BGTaskScheduler.shared.register(
forTaskWithIdentifier: "example.background.process",
using: nil
) { task in
self.handleBackgroundProcessing(task: task as! BGProcessingTask)
}
We schedule it using:
let request = BGProcessingTaskRequest(identifier: "example.background.process")
request.requiresNetworkConnectivity = true
request.requiresExternalPower = false
try BGTaskScheduler.shared.submit(request)
We also use Background URLSession:
let config = URLSessionConfiguration.background(withIdentifier: sessionId)
config.sessionSendsLaunchEvents = true
config.isDiscretionary = false
AppDelegate.handleEventsForBackgroundURLSession is implemented correctly and works in Debug.
Issue Observed (TestFlight Only)
In TestFlight builds:
BGProcessingTask rarely triggers, or the system marks it as NO LONGER RUNNING.
Background upload tasks sometimes never start or complete.
No logs appear from our BGProcessingTask handler.
system logs show messages like:
NO LONGER RUNNING bgProcessing-example.background.process
Tasks running in group [com.apple.dasd.defaultNetwork] are 1!
This occurs most frequently for large audio uploads (30–60 minutes), while small files behave normally.
What We Have Verified
Proper Info.plist values:
Permitted background modes: processing, audio, fetch
BGTaskSchedulerPermittedIdentifiers contains our identifier
BGProcessingTask is being submitted successfully (no errors)
App has microphone permission + background audio works
Device plugged/unplugged doesn’t change outcome
Key Question for Apple
We need clarification on:
Why BGProcessingTask behave differently between Debug and TestFlight builds?
Are there additional restrictions or heuristics (related to file size, CPU usage, runtime, network load, or power constraints) that cause BGProcessingTask to be throttled or skipped in Release/TestFlight?
How can we guarantee a background upload continues reliably for large files (100MB–500MB) on TestFlight and App Store builds?
Is there an Apple-recommended pattern to combine BGProcessingTask + Background URLSession for long-running uploads?
Expected Result
Background uploads should continue reliably for long audio files (>30 minutes) when the app goes to background or is terminated, in the same way they currently function in Debug builds.
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
iOS
Background Tasks
Foundation
CFNetwork
Regarding the Background Assets capability on iOS:
In the install scenario, resources defined as the "install" type are incorporated into the App Store download progress. Do resources of the "update" type in the update scenario also get incorporated into the App Store download progress in the same way?
If an exception occurs during the download of install-type resources and the download cannot proceed further, will the system no longer actively block users from launching the app and instead enable the launch button?
Currently, if a user has enabled automatic updates on their device, after the app is updated and released on the App Store, will the Background Assets download start immediately once the automatic update completes? Or does Background Assets have its own built-in scheduling logic that prevents it from running concurrently with the automatic update?
I posted here https://developer.apple.com/forums/thread/805554?page=1#867766022 but posting again for visibility (and let me know how I can file a bug)
There was a response in that thread that said you could use the childProgress system to help updating progresses to keep the backgroundTask alive.
What I've found is that using childProgresses results in more terminations than if you just updated the progress directly.
Here is my setups to test this
A BGContinuedProcessingTask that uses URLSessions to upload, and registers the task.progress with the Urlsession Progress
Same, but the task.progress gets updated via a UrlSession Callback
The second is MUCH more stable out in the field in cellular settings, the first fails extremely frequently.
My suspicion is that in the documentation here https://developer.apple.com/documentation/foundation/progress#Reporting-Progress-for-Multiple-Operations
it explicitly states
The completedUnitCount property for a containing progress object only updates when the suboperation is 100% complete. The fractionCompleted property for a containing progress object updates continuously as work progresses for all suboperations.
I wonder if BGContinuedProcessingTask is only looking at completedUnitCount for progress, and not fractionCompleted?
In either case, I would love to use the childProgresses because there are bugs with retries by updating the progress manually, so would love some help resolving this, Thanks!
I've tuned my task to be decently resilient, but I found a few issues that caused it to expire regularly.
excessive CPU usage -> I'm actually running it behind ReactNative, and I found an issue where I was still updating ReactNative and thus it was keeping it alive the entire time the task was running. Removing this update helped improve stability
not updating progress frequently enough ( see https://developer.apple.com/forums/thread/809182?page=1#868247022)
My feature request is, would it be possible to get a reason the task was expired in task.expirationHandler? That would be helpful for both the user and for debugging why the task was expired. Thanks!
We are seeing a strange lifecycle issue on multiple MDM-managed iPads where
application(_:didFinishLaunchingWithOptions:) is not called after the device is idle overnight.
Even if we terminate the app manually via the app switcher, the next morning the system does not perform a cold launch. Instead, the app resumes directly in:
applicationDidBecomeActive(_:)
This causes all initialization logic that depends on didFinishLaunching to be completely skipped.
This behavior is consistent across four different supervised MDM devices.
Environment
Devices: iPads enrolled in MDM (supervised)
iOS version: 18.3
Xcode: 16.4
macOS: Sequoia 15.7.2
App type: Standard UIKit iOS app
App: Salux Audiometer (App Store app)
Expected Behavior
If the app was terminated manually using the app switcher, the next launch should:
Start a new process
Trigger application(_:didFinishLaunchingWithOptions:)
Follow the normal cold-start lifecycle
Actual Behavior
After leaving the iPad idle overnight (8–12 hours):
The next launch skips didFinishLaunching
The app resumes directly in applicationDidBecomeActive
No new process is started
App behaves as if it had been suspended, even though it was manually terminated
Logs (Relevant Extracts)
Day 1 — Normal cold launch
[12:06:44.152 PM] PROCESS_STARTED
[12:06:44.214 PM] DID_FINISH_LAUNCHING_START launchOptions=[]
[12:06:44.448 PM] DID_FINISH_LAUNCHING_END
We then used the app and terminated it via app switcher.
Day 2 — Unexpected resume without cold start
[12:57:49.328 PM] APP_DID_BECOME_ACTIVE
No PROCESS_STARTED
No didFinishLaunching
No cold-start logs
This means the OS resumed the app from a previous state that should not exist.
Reproducible Steps
Use an MDM-enrolled iPad.
Launch the app normally.
Terminate it manually via the multitasking app switcher.
Leave the device idle overnight (8–12 hours).
Launch the app the next morning.
Observe that:
didFinishLaunching does not fire
applicationDidBecomeActive fires directly
Questions for Apple Engineers / Community
Is this expected behavior on MDM-supervised devices in iOS 18?
Are there any known OS-level changes where terminated apps may be revived from disk/memory?
Could MDM restrictions or background restoration policies override app termination?
How can we ensure that our app always performs a clean initialization when launched after a long idle period?
Additional Information
We have full logs from four separate MDM iPads showing identical behavior.
Happy to share a minimal reproducible sample if required.
Regarding App Update Synchronization During Workout Mode:
My watchOS app has workout mode enabled. When I update the app from the App Store on my iPhone while a workout session is active on my Apple Watch, the update does not sync to the watch. Why does this happen, and when can I expect the watch app to be updated?
Regarding Automatic App Launch After a Prolonged Shutdown:
I would like my watchOS app to launch automatically on my Apple Watch after it has been powered off for an extended period and then turned back on. Is this functionality possible to implement? If not, please provide a definitive answer regarding this capability.
I have an older project that was created before Xcode 26.2.
In Xcode versions prior to 26.2, there was no Swift Compiler – Concurrency build setting.
With those older versions, the following behavior occurs: a nonisolated function executes off the main thread.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
run()
}
private func run() {
Task {
await runInMainThread()
}
}
func runInMainThread() async {
print(">>>> IN runInMainThread(), Thread.isMainThread \(Thread.isMainThread)")
await runInBackgroundThread()
}
private nonisolated func runInBackgroundThread() async {
print(">>>> IN runInBackgroundThread(), Thread.isMainThread \(Thread.isMainThread)")
}
}
Output:
>>>> IN runInMainThread(), Thread.isMainThread true
>>>> IN runInBackgroundThread(), Thread.isMainThread false
However, starting with Xcode 26.2, Apple introduced the Swift Compiler – Concurrency settings.
When running the same code with the default configuration:
Approachable Concurrency = Yes
Default Actor Isolation = MainActor
This is the output
Output:
>>>> IN runInMainThread(), Thread.isMainThread true
>>>> IN runInBackgroundThread(), Thread.isMainThread true
the nonisolated function now executes on the main thread.
This raises the following questions:
What is the correct Swift Compiler – Concurrency configuration if I want a nonisolated function to run off the main thread?
Is nonisolated still an appropriate way to ensure code runs on a background thread?
I am developing a remote support tool for macOS. While we have successfully implemented a Privileged Helper Tool and LaunchDaemon architecture that works within an active Aqua session, we have observed a total failure to capture the screen buffer or receive input at the macOS Login Window.
Our observation of competitor software (AnyDesk, TeamViewer) shows they maintain graphical continuity through logout/restart. We are seeking the official architectural path to replicate this system-level access.
Current Technical Implementation
Architecture: A root-level LaunchDaemon manages the persistent network connection. A PrivilegedHelperTool (installed in /Library/PrivilegedHelperTools/) is used for elevated tasks.
Environment: Tested on macOS 14.x (Sonoma) and macOS 15.x (Sequoia) on Apple Silicon.
Capture Methods: We have implemented ScreenCaptureKit (SCK) as the primary engine and CGDisplayCreateImage as a fallback.
Binary Status: All components are signed with a Developer ID and have been successfully Notarized.
Observed Behavior & Blockers
The "Aqua" Success: Within a logged-in user session, our CGI correctly identifies Display IDs and initializes the capture stream. Remote control is fully functional.
The "Pre-Login" Failure: When the Mac is at the Login Window (no user logged in), the following occurs:
The Daemon remains active, but the screen capture buffer returns NULL or an empty frame.
ScreenCaptureKit fails to initialize, citing a lack of graphical context.
No TCC (Transparency, Consent, and Control) prompt can appear because no user session exists.
The "Bootstrap" Observation: We have identified that the loginwindow process exists in a restricted Mach bootstrap namespace that our Daemon (running in the System domain) cannot natively bridge.
Comparative Analysis (Competitor Benchmarking)
We have analyzed established remote desktop solutions like AnyDesk and Jump Desktop to understand their success at the login screen. Our findings suggest:
Dual-Context Execution: They appear to use a Global LaunchAgent with LimitLoadToSessionType = ["LoginWindow"]. This allows a child process to run as root inside the login window’s graphical domain.
Specialized Entitlements: These apps have migrated to the com.apple.developer.persistent-content-capture entitlement. This restricted capability allows them to bypass the weekly/monthly TCC re-authorization prompts and function in unattended scenarios where a user cannot click "Allow."
Questions
Entitlement Requirement: Is the persistent-content-capture entitlement the only supported way for a third-party app to capture the LoginWindow buffer without manual user intervention?
LaunchAgent Strategy: To gain a graphical context at the login screen, is it recommended to load a specialized agent into the loginwindow domain via launchctl bootstrap loginwindow ...?
ScreenCaptureKit vs. Legacy: Does ScreenCaptureKit officially support the LoginWindow session, or does it require an active Aqua session to initialize?
MDM Bypass: For Enterprise environments, can a Privacy Preferences Policy Control (PPPC) payload grant "Screen Recording" to a non-entitled Daemon specifically for the login window context?
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
macOS
Security
ScreenCaptureKit
Service Management
I tried making a concurrency-safe data queue. It was going well, until memory check tests crashed.
It's part of an unadvertised git project. Its location is:
https://github.com/CTMacUser/SynchronizedQueue/commit/84a476e8f719506cbd4cc6ef513313e4e489cae3
It's the blocked-off method "`memorySafetyReferenceTypes'" in "SynchronizedQueueTests.swift."
Note that the file and its tests were originally AI slop.
Knows anyone a point in systemlog etc. To find out when and why my or other apps are terminated by os.
At the moment a lot of apps inclusive my apps seems to be terminated instead set to sleep by OS if no power coord is connected
There are no crashlogs recorded, Sentry or firebase don‘t report issues.
Topic:
App & System Services
SubTopic:
Processes & Concurrency
I’ve built an app that connects via Bluetooth to a device. The device sends up, down, left and right commands.
I want to build an SDK for other third party developers to use so that whenever a third party app with the SDK opens, if we press a button on the device, my app which captures the button press should be able to forward the event to the third party app.
I want to achieve this with the lowest latency possible so that I can enable a variety of use cases like simple games and interactions within other apps.
What would be the best way for me to achieve this as part of my SDK and my app?
I'm working on an editor for Bevy games and wanted the following workflow:
Launch the game process
Host a Metal view for the game's render target
Use an XPC service to transfer an MTLSharedTextureHandle
Keep the connection for editor/game communication and hot reload
As such I created the following editor service:
public let XPCEditorServiceName = "org.bevy.editor"
public enum XPCEditorMessage: Codable {
case ping
}
public enum XPCEditorReply: Codable {
case pong
}
extension XPCListener {
static let bevy = try! XPCListener(service: XPCEditorServiceName) { request in
request.accept(XPCEditorService.init)
}
}
struct XPCEditorService: XPCPeerHandler {
let session: XPCSession
private func handle(_ message: XPCEditorMessage) -> XPCEditorReply? {
switch message {
case .ping:
return .pong
}
}
func handleIncomingRequest(_ message: XPCReceivedMessage) -> (any Encodable)? {
do {
return handle(try message.decode())
} catch {
return nil
}
}
func handleCancellation(error: XPCRichError) {
print(error)
}
}
and I initialize it in my app's App initializer:
// Launch the XPC service
print(XPCListener.bevy)
I wanted to test this using an executable target with the following main.swift:
let session = try XPCSession(xpcService: XPCEditorServiceName)
let response: XPCEditorReply = try session.sendSync(XPCEditorMessage.ping)
print("Connected to editor!")
The editor prints Listener<org.bevy.editor>(Active) but the game fails with Underlying connection was invalidated. Reason: Connection init failed at lookup with error 3 - No such process
What am I doing wrong?
PS. Would also appreciate an example of sending & rendering the MTLSharedTextureHandle both in editor & game.
I have migrated my code to use SMAppService but am running into trouble deleting the old SMJobBless launchd registration using launchd remove. I am invoking this from a root shell when I detect the daemon and associated plist still exist, then also deleting those files.
The remove seems to work (i.e. no errors returned) but launchd list shows the service is registered, with a status code of 28
I am using the same label for SMAppService as previously and suspect this is the reason for the problem. However, I am reluctant to change the label as there will a lot of code changes to do this.
If I quit my application, disable the background job in System Settings and run sudo launchd remove in the Terminal then it is removed and my application runs as expected once the background job is re-enabled. Alternatively, a reboot seems to get things going.
Any suggestions on to how I could do this more effectively welcome.
I have implemented a XPC server using C APIs. I want to write unit tests for it.
I came across the following links that use Swift APIs-
Testing and Debugging XPC Code With an Anonymous Listener
TN3113
I have tried to write anonymous listener code and the client code in the same file, using C APIs-
#include <unistd.h>
#include <syslog.h>
#include <pthread.h>
#include <stdio.h>
#include <xpc/xpc.h>
#include <xpc/connection.h>
#include <CoreFoundation/CoreFoundation.h>
static void Anon_Client_Connection_Handler(xpc_connection_t connection, xpc_object_t clientMessage)
{
const char *description = xpc_copy_description(clientMessage);
printf("Event received - %s\n", description);
free((void *)description);
xpc_type_t type = xpc_get_type(clientMessage);
if (type == XPC_TYPE_ERROR)
{
if (clientMessage == XPC_ERROR_CONNECTION_INVALID)
printf("Client_Connection_Handler received invalid connection n");
else if (clientMessage == XPC_ERROR_TERMINATION_IMMINENT)
printf("Client_Connection_Handler received termination notice n");
}
else
{
const char *clientMsg = xpc_dictionary_get_string(clientMessage, "message");
printf("Received from client: %s ", clientMsg);
}
}
static void Anon_Listener_Connection_Handler(xpc_connection_t connection)
{
printf("Anon_Listener_Connection_Handler called, setting up event handler \n");
xpc_connection_set_event_handler(connection, ^(xpc_object_t clientMessage) {
printf("Processing the connection! \n");
Anon_Client_Connection_Handler(connection, clientMessage);
});
xpc_connection_resume(connection);
}
int main(int argc, const char *argv[])
{
xpc_connection_t anon_listener = xpc_connection_create(NULL, NULL);
xpc_connection_set_event_handler(anon_listener, ^(xpc_object_t clientConnection) {
printf("Client tried to connect \n");
Anon_Listener_Connection_Handler(clientConnection);
});
xpc_connection_resume(anon_listener);
printf("\nINFO Anonymous connection resumed");
xpc_object_t anon_endpoint = xpc_endpoint_create(anon_listener);
xpc_connection_t clientConnection = xpc_connection_create_from_endpoint(anon_endpoint);
xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_string(message, "message", "client's message");
xpc_connection_send_message_with_reply(clientConnection, message, dispatch_get_main_queue(), ^(xpc_object_t event) {
printf("\nINFO inside reply");
const char *description = xpc_copy_description(event);
printf("\nINFO %s",description);
free((void *)description);
});
xpc_release(message);
xpc_release(anon_listener);
printf("\nINFO Releasing listener");
xpc_release(anon_endpoint);
printf("\nINFO Releasing endpoint");
// dispatch_main();
return 0;
}
and this is the output I get
INFO Anonymous connection resumed
INFO Releasing listener
INFO Releasing endpoint
I am not able to connect to the client and exchange messages. Where am I going wrong?
We are building a 'server' application that can either run as a daemon or can run in background without showing any GUI. Basically, the end user can either configure this to run as a daemon so that it can be tied to the user's session or will launch the process which user will start and quit as needed.
I wanted to understand what is the recommended mechanism for such an application from Apple -
Should this application be built as a macOS Bundle ? Apple documentation also says that we should not daemonize the process by calling fork. Hence if we create a unix-style executable, will I not need to fork to make it run in a detached state when I launch the executable via double-click ? [Reference Link]
Is it fine to have an application on macOS which is a bundle but does not show any UI when launched by double click on the app-icon or via 'open'? While we have been able to achieve this by using NSApplicationMain and not showing the UI, was wondering if using CFRunLoop is best for this case as it is a non-gui application.
If we can get the right documentation link or recommendations on how we should build such an application which can run in a non-gui mode and also in a daemonized manner, it will help us.
Should the application be always built as a macos bundle or should it be a unix-style executable to support both the cases - by the same application/product and how should we look at the distribution of such applications.
I have an XPC server running on macOS and want to perform comprehensive performance and load testing to evaluate its efficiency, responsiveness, and scalability. Specifically, I need to measure factors such as request latency, throughput, and how well it handles concurrent connections under different load conditions.
What are the best tools, frameworks, or methodologies for testing an XPC service? Additionally, are there any best practices for simulating real-world usage scenarios and identifying potential bottlenecks?
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
XPC
Endpoint Security
Instruments
Performance
Hello,
I'm experiencing an issue with my app where it's being terminated by the system with a watchdog violation during back-to-back messaging operations. I've analyzed the crash logs but would appreciate additional insights on optimizing my approach. I'd appreciate any insights on how to resolve this problem.
Crash Details:
Exception Type: EXC_CRASH (SIGKILL)
Termination Reason: FRONTBOARD with code 0x8BADF00D
Error: "scene-update watchdog transgression: app exhausted real time allowance of 10.00 seconds"
Reproduction Steps:
User A initiates back-to-back messages to other User
User A's UI becomes unresponsive and eventually the app crashes.
Stack Trace Analysis:
The crash occurs on the main thread, which appears to be blocked waiting for a condition in the keyboard handling system. The thread is stuck in [UIKeyboardTaskQueue _lockWhenReadyForMainThread] and related methods, suggesting an issue with keyboard-related operations during the messaging process.
Crash Tag
Exception Type: EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: FRONTBOARD 2343432205
<RBSTerminateContext| domain:10 code:0x8BADF00D explanation:scene-update watchdog transgression: app<com.msikodiak.eptt(AD934F8A-DF57-4B75-BE73-8CF1A9A8F856)>:301 exhausted real (wall clock) time allowance of 10.00 seconds
ProcessVisibility: Foreground
ProcessState: Running
WatchdogEvent: scene-update
WatchdogVisibility: Background
WatchdogCPUStatistics: (
"Elapsed total CPU time (seconds): 6.390 (user 3.640, system 2.750), 11% CPU",
"Elapsed application CPU time (seconds): 0.020, 0% CPU"
)
ThermalInfo: (
"Thermal Level: 0",
"Thermal State: nominal"
) reportType:CrashLog maxTerminationResistance:Interactive>
Triggered by Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x1e773d438 __psynch_cvwait + 8
1 libsystem_pthread.dylib 0x2210bc328 _pthread_cond_wait + 1028
2 Foundation 0x1957d8a64 -[NSCondition waitUntilDate:] + 132
3 Foundation 0x1957d8888 -[NSConditionLock lockWhenCondition:beforeDate:] + 80
4 UIKitCore 0x1998f1238 -[UIKeyboardTaskQueue _lockWhenReadyForMainThread] + 456
5 UIKitCore 0x19a3d775c __59-[UIKeyboardImpl updateAutocorrectPrompt:executionContext:]_block_invoke_9 + 28
6 UIKitCore 0x19986b084 -[UIKeyboardTaskQueue lockWhenReadyForMainThread] + 168
7 UIKitCore 0x19a3f2994 -[UIKeyboardTaskQueue waitUntilTaskIsFinished:] + 148
8 UIKitCore 0x19a3f2ac4 -[UIKeyboardTaskQueue performSingleTask:breadcrumb:] + 132
9 UIKitCore 0x199e2f7e4 -[_UIKeyboardStateManager updateForChangedSelection] + 144
10 UIKitCore 0x199e24200 -[_UIKeyboardStateManager invalidateTextEntryContextForTextInput:] + 92
11 WebKit 0x1ad52fa54 WebKit::PageClientImpl::didProgrammaticallyClearFocusedElement(WebCore::ElementContext&&) + 40
12 WebKit 0x1ad55adcc WebKit::WebPageProxy::didProgrammaticallyClearFocusedElement(WebCore::ElementContext&&) + 136
13 WebKit 0x1acec74e8 WebKit::WebPageProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) + 18604
14 WebKit 0x1acd21184 IPC::MessageReceiverMap::dispatchMessage(IPC::Connection&, IPC::Decoder&) + 236
15 WebKit 0x1ace449b8 WebKit::WebProcessProxy::dispatchMessage(IPC::Connection&, IPC::Decoder&) + 40
16 WebKit 0x1ace44228 WebKit::WebProcessProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) + 1764
17 WebKit 0x1acd1e904 IPC::Connection::dispatchMessage(WTF::UniqueRef<IPC::Decoder>) + 268
18 WebKit 0x1acd1e478 IPC::Connection::dispatchIncomingMessages() + 576
19 JavaScriptCore 0x1ae386b8c WTF::RunLoop::performWork() + 524
20 JavaScriptCore 0x1ae386960 WTF::RunLoop::performWork(void*) + 36
21 CoreFoundation 0x196badce4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28
22 CoreFoundation 0x196badc78 __CFRunLoopDoSource0 + 172
23 CoreFoundation 0x196bac9fc __CFRunLoopDoSources0 + 232
24 CoreFoundation 0x196babc3c __CFRunLoopRun + 840
25 CoreFoundation 0x196bd0700 CFRunLoopRunSpecific + 572
26 GraphicsServices 0x1e3711190 GSEventRunModal + 168
27 UIKitCore 0x1997ee240 -[UIApplication _run] + 816
28 UIKitCore 0x1997ec470 UIApplicationMain + 336
29 Telstra PTT 0x1004d30c8 main + 56
30 dyld 0x1bd5d3ad8 start + 5964
Basically the title. I am trying to implement a local notification to trigger, regardless of internet connection, around 3-5pm if a certain array in the app is not empty to get the user to sync unsaved work with the cloud. I wanted to used the BGAppRefreshTask as I saw it was lightweight and quick for just posting a banner notification but after inspecting it in the console, it looks like it needs internet connection to trigger. Is this the case or am I doing something wrong? Should I be using the BGProcessingTask instead?
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
Background Tasks
User Notifications