Hello,
When my mobile app is terminated, say 30 secs later the CarPlay app stops working. I don't get the access token that is saved in the KeyChain. The same happens when my mobile app is in background for more than 20 secs or so.
Please suggest the way forward. Or is this the expected behavior?
Background Tasks
RSS for tagRequest the system to launch your app in the background to run tasks using Background Tasks.
Posts under Background Tasks tag
157 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Nice to meet you,
I'm currently trying to create an app like a data logger using BLE.
When a user uses the above app, they will probably put the app in the background and lock their iPhone if they want to collect data for a long period of time.
Therefore, the app I want to create needs to continue scanning for BLE even when it goes into the background.
The purpose is to continue to obtain data from the same device at precise time intervals for a long period of time (24 hours).
In that case, can I use the above function to continue to read and record advertising data from the same device periodically (at intervals of 10 seconds, 1 minute, or 5 minutes) after the app goes into the background?
Any advice, no matter how small, is welcome.
Please feel free to reply.
Also, if you have the same question in this forum and it has already been answered, I would appreciate it if you could let me know.
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!.
Hello.
Background: Most learning resources are for leaning Swift/Objective-C. I'm pretty sure I need something different. I'm already an experienced software engineer, just new to iOS/MacOS development. My problem is not learning the language, but rather how to learn modern best practices. I cannot find examples for what I'm looking for. So much seems to be sparse on implementation details, out of date, or both.
I'm trying to write an app that has a few distinct parts. The UI portion will be mostly a menu bar app, which I am not having a problem discovering resources for how to implement. The app will also have a daemon and utilize network extensions. This is where I am having trouble.
What's the current best practices on how to write and launch a daemon?
Should the daemon be its own library/package which is them imported into the main app? If so, which Xcode template do I use for this? Are there any Hello World! examples of this?
What is the best way for a UI app to communicate with a daemon?
Are there any Hello World! repositories on how to implement network extensions? Should this be done in the main UI app, or in a separate library/package?
TIA
Topic:
App & System Services
SubTopic:
General
Tags:
Network Extension
Service Management
Background Tasks
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
I have an app that uses background audio recording. From what others say, I have enabled the audio background mode to keep the audio session active, and this worked. But when submitting the app to the app store, the app was rejected because the audio background mode is only supposed to be used for audio playback.
How do I create this background mode while following Apple's guidelines?
I'm developing a medication scheduling app similar to Apple Health's Medications feature, and I'd like some input on my current approach to background tasks.
In my app, when a user creates a medication, I generate ScheduledDose objects (with corresponding local notifications) for the next 2 weeks and save them to SwiftData. To ensure this 2-week window stays current, I've implemented a BGAppRefreshTask that runs daily to generate new doses as needed.
My concern is whether BGAppRefreshTask is the appropriate mechanism for this purpose. Since I'm not making any network requests but rather generating and storing local data, I'm questioning if this is the right approach.
I'm also wondering how Apple Health's Medications feature handles this kind of scheduling. Their app seems to maintain future doses regardless of app usage patterns.
Has anyone implemented something similar or can suggest the best background execution API for this type of scenario?
Thanks for any guidance you can provide.
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
HealthKit
SwiftUI
Background Tasks
SwiftData
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];
We’re receiving increasing user reports that our macOS app is unexpectedly terminated in the background—without crash reports or user action.
Our app is a sandboxed status-bar app (UIElement, NSStatusItem) running continuously, syncing data via CloudKit and Core Data. It has no main window unless opened via the status bar.
Observed patterns:
Happens more frequent on macOS 15 (Sonoma), though earlier versions are affected too.
Often occurs when disk space is limited (~10% free), but occasionally happens with ample free space.
System logs consistently show: CacheDeleteAppContainerCaches requesting termination assertion for <our bundle ID>
No crash reports are generated, indicating macOS silently terminates our app, likely related to RunningBoard or CacheDelete purging caches during disk pressure. Since our app is meant to run persistently, these silent terminations significantly disrupt user experience.
We’re seeking guidance on:
Can we prevent or reduce these terminations for persistently running status bar apps?
Are there recommended APIs or configurations (e.g., NSProcessInfo assertions, entitlements, LaunchAgents) to resist termination or receive notifications under low disk conditions?
What are Apple’s best practices for ensuring sandboxed apps reliably run during disk pressure?
We understand macOS terminates apps to reclaim space but would appreciate recommendations to improve resilience within platform guidelines.
Thank you!
Topic:
App & System Services
SubTopic:
Core OS
Tags:
App Sandbox
Core Services
Background Tasks
Files and Storage
I’m building a companion app that connects to a custom hardware hub (IoT device) used for home safety monitoring. The hub is installed in homes and is responsible for triggering critical alerts like fire alarms, motion detection, door sensor activity, and baby monitor events.
Current Architecture:
The hub initially connects to the app via Bluetooth (BLE) for provisioning (to get Wi-Fi credentials).
Once provisioned, the hub switches to Wi-Fi and communicates with the app via a WebSocket connection to stream real-time event updates.
What I’m Trying to Achieve:
My goal is to maintain background communication with the hub even when the app is not actively in use, in order to:
Receive real-time updates from the hub while the device is locked or the app is in background.
Trigger local notifications immediately when critical sensor events (e.g., fire, motion) occur.
Ensure persistence across backgrounding, app swipes (force close), and device reboots, if possible.
What I'm Observing:
On iOS, WebSocket connection is suspended or dropped shortly after the app goes to the background or is locked.
Even though the I've scheduled periodic fetches, notifications are delayed until the app is reopened, at which point all missed WebSocket messages arrive at once.
If the app is force-closed or after reboot, no reconnection or notification happens at all.
Key Questions I Have:
Since the hub is initially provisioned via BLE, and could potentially send BLE flags or triggers for key events, can I use bluetooth-central mode to keep the app active or wake it up on BLE activity?
Once the hub switches to Wi-Fi and uses WebSocket, is it possible to combine BLE triggers to wake the app and then reconnect to the WebSocket to fetch the full event payload?
Is there a legitimate and App Store-compliant way to maintain a connection or background task with:
BLE accessory triggers followed by
Real-time data processing via Wi-Fi/WebSocket?
Would this use case qualify as a "companion device" scenario under iOS background execution policies?
What is the best practice for handling this kind of hybrid BLE + WebSocket alerting flow to ensure timely user notifications, even in background/locked/force-closed states?
Any advice, documentation links, implementation patterns, or examples from similar companion device apps would be greatly appreciated. Thanks in advance!
Topic:
App & System Services
SubTopic:
Core OS
Tags:
User Notifications
Background Tasks
Core Bluetooth
Hi everyone!
I’ve developed a location-based Audio AR app in Unity with FMOD & Resonance Audio and AirPods Pro Head-Tracking to create a ubiquitous augmented soundscape experience. Think of it as an audio version of Pokémon Go, but with a more precise location requirement to ensure spatial audio is placed correctly.
I want this experience to run in the background on iOS, but from what I’ve gathered, it seems Unity doesn’t support this well. So, I’m considering developing a Swift version instead.
Since this is primarily for research purposes, privacy concerns are not a major issue in my case. However, I’ve come across some potential challenges:
Real-time precise location updates – Can iOS provide fully instantaneous, high-accuracy location updates in the background?
Continuous real-time data processing – Can an app continuously process spatial audio, head-tracking, and location data while running in the background?
I’m not sure if newer iOS versions have improved in these areas or if there are workarounds to achieve this.
Would this kind of experience be feasible to run in the background on iOS? Any insights or pointers would be greatly appreciated!
I’m very new to iOS development, so apologies if this is a basic question. Thanks in advance!
I'm trying to schedule a background task that will run on an iPhone and I'm looking into creating a task request using BGProcessingTaskRequest and scheduled it using BGTaskScheduler.shared.submit().
Per earliestBeginDate documentation, this property can be used to specify the earliest time a background task will be launched by OS. All clear here.
However, the question is: how is the value interpreted with respect to timezone ? Is the specified date in device timezone ? Is GMT ? Is something else ?
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
iOS
Background Tasks
Foundation
Hello everyone!
I'm having a problem with background tasks running in the foreground.
When a user enters the app, a background task is triggered. I've written some code to check if the app is in the foreground and to prevent the task from running, but it doesn't always work. Sometimes the task runs in the background as expected, but other times it runs in the foreground, as I mentioned earlier.
Could it be that I'm doing something wrong? Any suggestions would be appreciated.
here is code:
class BackgroundTaskService {
@Environment(\.scenePhase) var scenePhase
static let shared = BackgroundTaskService()
private init() {}
// MARK: - create task
func createCheckTask() {
let identifier = TaskIdentifier.check
BGTaskScheduler.shared.getPendingTaskRequests { requests in
if requests.contains(where: { $0.identifier == identifier.rawValue }) {
return
}
self.createByInterval(identifier: identifier.rawValue, interval: identifier.interval)
}
}
private func createByInterval(identifier: String, interval: TimeInterval) {
let request = BGProcessingTaskRequest(identifier: identifier)
request.earliestBeginDate = Date(timeIntervalSinceNow: interval)
scheduleTask(request: request)
}
// MARK: submit task
private func scheduleTask(request: BGProcessingTaskRequest) {
do {
try BGTaskScheduler.shared.submit(request)
} catch {
// some actions with error
}
}
// MARK: background actions
func checkTask(task: BGProcessingTask) {
let today = Calendar.current.startOfDay(for: Date())
let lastExecutionDate = UserDefaults.standard.object(forKey: "lastCheckExecutionDate") as? Date ?? Date.distantPast
let notRunnedToday = !Calendar.current.isDate(today, inSameDayAs: lastExecutionDate)
guard notRunnedToday else {
task.setTaskCompleted(success: true)
createCheckTask()
return
}
if scenePhase == .background {
TaskActionStore.shared.getAction(for: task.identifier)?()
}
task.setTaskCompleted(success: true)
UserDefaults.standard.set(today, forKey: "lastCheckExecutionDate")
createCheckTask()
}
}
And in AppDelegate:
BGTaskScheduler.shared.register(forTaskWithIdentifier: "check", using: nil) { task in
guard let task = task as? BGProcessingTask else { return }
BackgroundTaskService.shared.checkNodeTask(task: task)
}
BackgroundTaskService.shared.createCheckTask()
Hello, aspiring programmer here.
I am developing a StepCounter APP, which keeps track of how many steps I have taken and sends to an MQTT server. I am trying to make this happen even while the app is not in focus, but so far I have not been able to get this working.
First tried with silent background music, which seemed pretty inconsistent and inpractical, since I usually play youtube videoes while walking, making the app stop with its silent audio. Then tried GPS, which didnt really do anything (could be implementation problem).
Has anyone made background processing work for their apps?
Hello, aspiring programmer here.
I am developing a StepCounter APP, which keeps track of how many steps I have taken and sends to an MQTT server. I am trying to make this happen even while the app is not in focus, but so far I have not been able to get this working.
First tried with silent background music, which seemed pretty inconsistent and inpractical, since I usually play youtube videoes while walking, making the app stop with its silent audio. Then tried GPS, which didnt really do anything (could be implementation problem).
Has anyone made background processing work for their apps?
If new photo is added to library and app is not running in foreground or was not opened after the new photo was added but the app is having full access to gallery, can it access, read the new photo - If the app is not specifically a cloud syncing app, can it have this attached function, suppose it is a game app or beauty camera app?
Topic:
Media Technologies
SubTopic:
Photos & Camera
Tags:
Privacy
PhotoKit
Background Tasks
Background Assets
Hi everyone,
We're experiencing an issue with our Flutter app that uses PushKit, CallKit, and Janus for handling VoIP calls. Everything works fine when the app is in the foreground, but when the app is in the background or completely closed (terminated state), the behavior is inconsistent:
Sometimes, incoming calls are received as expected.
Other times, the app does nothing, and the call is not delivered at all.
Upon checking the console logs, we noticed that our app is being canceled (terminated by the system), which seems to be the reason why calls are not coming through. This happens randomly, making it difficult to reproduce consistently.
Additional Details:
The app is configured to handle VoIP notifications correctly.
We are using PushKit to wake up the app and trigger CallKit for the incoming call UI.
When the app is active, calls are handled correctly via Janus WebRTC signaling.
We have verified that background modes for VoIP are enabled in the Info.plist.
We suspect that iOS may be aggressively killing the app in the background, preventing incoming call notifications from reaching it.
Questions:
Has anyone experienced similar behavior with PushKit + CallKit on recent iOS versions?
Could iOS be terminating the app due to background execution policies?
Are there recommended best practices to ensure reliable delivery of VoIP notifications when the app is closed?
Any insights or suggestions would be greatly appreciated!
Thanks!
Addional Information:
this is the cancellation information at console: Received incoming message on topic hiperme.app at priority 10
por omisión 17:10:18.462084-0300 dasd CANCELED: com.apple.pushLaunch.hiperme.app:E8BACD at priority 10
I have BGProcessingTask & BGAppRefreshTask working fine. The main purpose of my use of BGProcessingTask is to upload a file to AWS S3 using multipart/form-data. I have found that any file above about 2.5MB times out after running almost four minutes. If I run the same RESTful api using curl or Postman, I can upload a 25MB file in 3 seconds or less.
I have tried to deliberately set .earliestBeginDate to 01:00 or 02:00 local time on the iPhone, but that does not seem to help.
I use the delegate (yes, I am writing in Objective C) - URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend: and find that the iOS system uploads about 140kB every 15 seconds or so.
I am looking for recommendations or insight into how I might enable uploads of 25MB files. I would be happy it I could do just one a day for my use case.
I provide code on how I set up the NSURLSession and NSURLSessionDownloadTask, as it is my guess that if there is something that needs to be modified it is there.
I have to believe there is a solution for this since I read in many posts here and in StackOverflow how developers are using this functionality for uploading many, many files.
NSURLSessionConfiguration *sConf = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:bkto.taskIdentifier];
sConf.URLCache = [NSURLCache sharedURLCache];
sConf.waitsForConnectivity = YES;
sConf.allowsCellularAccess = NO;
sConf.networkServiceType = NSURLNetworkServiceTypeVideot;
sConf.multipathServiceType = NSURLSessionMultipathServiceTypeNone;
sConf.discretionary = YES;
sConf.timeoutIntervalForResource = kONEHOURINTERVAL;
sConf.timeoutIntervalForRequest = kONEMINUTEINTERVAL;
sConf.allowsExpensiveNetworkAccess = NO ;
sConf.allowsConstrainedNetworkAccess = NO;
sConf.sessionSendsLaunchEvents = YES;
myURLSession = [NSURLSession sessionWithConfiguration:sConf delegate:self delegateQueue:nil];
And then later in the code...
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:pth]];
request.HTTPMethod = kHTTPPOST;
request.HTTPBody = [NSData my body data];
request.timeoutInterval = 60;
[request setValue:@"*/*" forHTTPHeaderField:@"Accept"];
[request setValue:@"en-us,en" forHTTPHeaderField:@"Accept-Language"];
[request setValue:@"gzip, deflate, br" forHTTPHeaderField:@"Accept-Encoding"];
[request setValue:@"ISO-8859-1,utf-8" forHTTPHeaderField:@"Accept-Charset"];
[request setValue:@"600" forHTTPHeaderField:@"Keep-Alive"];
[request setValue:@"keep-alive" forHTTPHeaderField:@"Connection"];
NSString *contType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",bnd];
[request setValue:contType forHTTPHeaderField:@"Content-Type"];
[request addValue:[NSString stringWithFormat:@"%lu",(unsigned long)myData.length] forHTTPHeaderField:@"Content-Length"];
and here are a few lines from my logs to show the infrequent multi-part uploads of only small chunks of data by the iOS system:
-[BKSessionManager URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]: bytesSent = 393,216
-[BKSessionManager URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]: totalBytesSent = 393,216
-[BKSessionManager URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]: task = BackgroundDownloadTask <76A81A80-4703-4686-8742-A0048EB65108>.<2>, time Fri Mar 7 16:25:27 2025
-[BKSessionManager URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]: bytesSent = 131,072
-[BKSessionManager URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]: totalBytesSent = 524,288
-[BKSessionManager URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]: task = BackgroundDownloadTask <76A81A80-4703-4686-8742-A0048EB65108>.<2>, time Fri Mar 7 16:25:42 2025
-[BKSessionManager URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]: bytesSent = 131,072
-[BKSessionManager URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]: totalBytesSent = 655,360
-[BKSessionManager URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]: task = BackgroundDownloadTask <76A81A80-4703-4686-8742-A0048EB65108>.<2>, time Fri Mar 7 16:25:56 2025
-[BKSessionManager URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]: bytesSent = 131,072
-[BKSessionManager URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]: totalBytesSent = 786,432
My team is designing an app for retail associates that need to share managed iPads. We keep the app in Guided Access mode on our login app until an auth token is obtained. Then the iPad is opened for general use. Upon signout we need to re-enter guided access mode and we can do this via manual signout easily. But with idle signout, ie after 60 minutes of inactivity, we need to be able to make a call from the background (in a locked state even) and sign out the user, clear the pin code and enter single app mode before restarting. So that hopefully once the device restarts, we have the app in a locked state again until the next user provides credentials that can obtain a new auth token.
We are struggling to see if this is even possible. Our bosses will be displeased if we tell them it isn't. So anybody with any tips would be very appreciated.
I've been reading this question: https://developer.apple.com/forums/thread/701945 and watching the videos on background tasks
But can't arrive to a concrete solution.
Q1: Are there any tips (or sample app) on how to handle a launch in background in a streamlined way? How to have a shared code that is ran for both 'launch in background' & 'launch in foreground'?
Specifically the case I'm talking about is:
You set up some observance of some OS callback at a Foo screen of your app. Example app should request and then send push-to-start live activity tokens to server. Or setup location tracking.
App is then suspended and then later terminated but is eligible for relaunch
App is then launched in background because it has requested a push-to-start live activity token or an update for location tracking.
User DOES NOT go back to screen Foo.
So at this point app is no longer tracking / listening to updates for token update or location changes.
How should I architecture my code for this? I'm trying to see if there's a an approach where I can avoid having multiple places in code where I do the same thing. Currently what I'm doing is as such:
Q2: Is it then correct to say that anytime you've launched your app, whether it's in foreground or background then you must immediately match 'all observations done by the previous app launch'?
Like store items in UserDefaults and upon launch retrieve them and do:
handleGeneralAppLaunchFlow()
// ALSO
if defaults.contains("didLastLaunchSetupLiveActivtiyTokenObservance") {
for await ptsToken in Activity<EmojiRangers> .pushToStartTokenUpdates {
...
}
}
if defaults.contains("didLastLaunchSetupLocationTracking") {
locationManager = CLLocationManager()
locationManager?.delegate = itsDelegate
locationManager?.allowsBackgroundLocationUpdates = true
locationManager?.showsBackgroundLocationIndicator = true
locationManager?.startUpdatingLocation()
}
// Other checks for prior observance setup
Q3: Actually I think even if app is launched in foreground then because you may not end up at screen Foo again, then you must setup things regardless of app state and just based on prior observations set. Right?
Q4: And then later if the user ever made it again to screen Foo, then we just skip the re-do of the observance, or maybe to just keep things simple, we'd just redo without over-engineering things?
I tried to mark my questions with Q1- Q4.