Background Tasks

RSS for tag

Request the system to launch your app in the background to run tasks using Background Tasks.

Background Tasks Documentation

Pinned Posts

Posts under Background Tasks tag

140 Posts
Sort by:
Post not yet marked as solved
0 Replies
464 Views
I'm trying to add Background Tasks to my SwiftUI app using the modifier backgroundTask(_:action:). I've been unable to get a working example, nothing ever updates in my app in the "background". I've added the identifier to the permitted background task scheduler identifiers , enabled the required background modes capabilities. Any help would be appreciated. It appears that neither appRefresh nor urlSession background tasks are effective in handling the update of JSON data in my app. Also which background task would be best suited for updating json data for my app? When debugging and launching using e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"apprefresh"] doesn't get called on a real device. App struct MyApp: App { @State private var viewModel = ViewModel() var body: some Scene { WindowGroup { ContentView() .environment(viewModel) } .backgroundTask(.appRefresh("apprefresh")) { scheduleAppRefresh() await viewModel.appRefresh() } .backgroundTask(.urlSession("apprefresh")) { scheduleAppRefresh() await viewModel.urlSession() } .onChange(of: phase) { switch phase { case .background: scheduleAppRefresh() default: break } } } func scheduleAppRefresh() { let request = BGAppRefreshTaskRequest(identifier: "apprefresh") request.earliestBeginDate = .now.addingTimeInterval(15 * 60) try? BGTaskScheduler.shared.submit(request) } } ViewModel @Observable class ViewModel { func appRefresh( ) async { } func urlSession( ) async { let config = URLSessionConfiguration.background( withIdentifier: "apprefresh" ) config.sessionSendsLaunchEvents = true let session = URLSession( configuration: config ) let request = URLRequest( url: URL( string: "" )! ) let response = await withTaskCancellationHandler { try? await session.data( for: request ) } onCancel: { let task = session.downloadTask( with: request ) task.resume() } } }
Posted Last updated
.
Post not yet marked as solved
0 Replies
255 Views
I have a BLE device and the centralManger scans with "centralManager.scanForPeripherals(withServices: [connectionServiceUUID], options: nil)" Then func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { ... } is called. Here, I could get the advertisementData[CBAdvertisementDataLocalNameKey]. I have set my BLE device to change its local name key for every connections. The BLE communication is repeated in the background.(scan, connect, stop scan, disconnect, ... etc) It works well, but when the screen is off, the value of advertisementData[CBAdvertisementDataLocalNameKey] in didDiscover does not change. Why?
Posted
by Leo_Choi.
Last updated
.
Post not yet marked as solved
3 Replies
1.1k Views
I'm trying to set up background HTTP upload requests (syncing files from the user's phone to a server) that trigger periodically in my Swift app. I don't have strict requirements on when this runs (it can happen overnight or throughout the day). I know Apple provides several APIs for background tasks on iOS (beginBackgroundTask, BGAppRefreshTaskRequest, BGProcessingTaskRequest, URLSession upload vs. background session). And I've seen this post on the Apple developer forums that attempts to explain the differences and when to use which - as well as Apple's page on the subject, but it's still not clear to me how a few of these work in practice, and thus which ones I should utilize for my use case. My questions: How should I schedule periodic file upload tasks in the background? I assume I should use BGProcessingTaskRequest, since I don't know exactly how long the task will take (it could be syncing just 1-2 files, or it could be hundreds) and I don't care if it runs overnight How should I ensure foreground tasks are able to complete after closing the app? (i.e. when a user starts a sync manually in the app) From Apple's page on URLSessionUploadTask: "Unlike data tasks, you can use upload tasks to upload content in the background." Does this mean any requests I make using URLSession.shared.upload() will automatically run in the background if the user closes the app? Even with the async/await version, or do I have to use the completionHandler version? Do I need to call beginBackgroundTask if I'm using URLSession.shared.upload() to guarantee I get more time to finish uploads? What about sequential requests (i.e. requests that haven't started yet by the time the app is closed)? Based on this StackOverflow response, it sounds like I may need to trigger all the uploads in parallel beforehand? https://stackoverflow.com/a/53949607/2359478 Should I even consider URLSessionConfiguration.background for my use case? It sounds like it I use beginBackgroundTask and BGProcessingTaskRequest then this may be unnecessary? Thanks!
Posted Last updated
.
Post not yet marked as solved
0 Replies
505 Views
Hello Apple Community, I am writing to discuss a limitation I’ve encountered with third-party alarm clock apps on iOS. As it stands, these apps are unable to function like the native Clock app, primarily due to the restrictions imposed by the operating system. Currently, third-party alarm apps rely on standard local notifications, which fire once and then cease. This means that if a user misses the initial notification, there’s no backup mechanism to ensure they are alerted. This is a significant drawback for users who rely on these apps to manage their time effectively. Moreover, some apps have found a workaround by playing a silent sound in the background to keep the app active. However, this method is not only against Apple’s guidelines but also drains the device’s battery life. I propose that Apple consider allowing third-party apps to push notifications from the background in an alarm style, with clear permissions granted by the user. This would enable users to clearly define acceptable notifications and specify an alarm-like display, providing a more personalized and effective alarm experience. By implementing this change, Apple could greatly enhance the functionality and user-friendliness of third-party alarm clock apps, ultimately benefiting the end-users and developers alike. Because this alarm feature is so important for productivity and quick responses to critical events or triggers I'm trying to see how some concepts could be reimagined if we had a little more flexibility. Apple iOS has a feature called StandBy mode that activates when an iPhone is charging and positioned on its side. This feature can be thought of as a kind of smart display for your iPhone that offers fast access to different screens of glanceable information. Always-On Display: StandBy mode can keep the display on even when the phone is locked, which is useful for an alarm app. Users can glance at the time without having to unlock their phone w/ Low-Light Adaptation Customizable Screens: StandBy mode consists of screens that can be accessed by swiping horizontally on your iPhone’s display. This could allow an alarm app to display additional information, such as route, or weather warnings. Interactive Widgets: The widget screen in StandBy mode is interactive and customizable. I look forward to hearing your thoughts on this matter. Best regards, Phil Cutting
Posted Last updated
.
Post not yet marked as solved
1 Replies
497 Views
Description We have a sidebar-detail layout in our app. Since we moved from NavigationView on iOS 15 to NavigationSplitView on iOS 16, we've seen some issues. On iOS 16, the app is always killed, or reset, when the app enters background. That means whatever the sidebar and detail view show, they will almost always return to the initial blank screen state when coming back from background. On iOS 17, the background issue is mitigated. However, the toolbar button is missing after coming back from background. Those problem aren't present in NavigationView on iOS 15. Steps to Repro General steps… Create a new iOS app demo project with deployment target min version set to iOS 16. Copy and paste the code snippet below into ContentView.swift. Run the app on iPad simulator with the respective Simulator OS versions. iOS 16 Tap the info button on the side bar, it presents a "form sheet" style page. Put the app into background. Open any app. I opened the Photos app. Switch back to the demo app. The sheet is dismissed and the app returns to the initial state, which indicates the app was reset in the background. When I tap the info button again, it doesn't present a sheet. iOS 17 Same steps as 1-3 above for iOS 16. Switch back to the test app. The sheet is not dismissed, which means the app wasn't reset in the background. However, you can see the info button is missing from the sidebar's top toolbar. Similar Posts NavigationSplitView resetting when app enters background: https://developer.apple.com/forums/thread/733472 Selection state is lost when navigating to/from home screen: https://developer.apple.com/forums/thread/728657 SwiftUI NavigationSplitView looses toolbar button when App moves to background - iOS 17 / Xcode 15.0: https://stackoverflow.com/questions/77253055 Repro Code Snippet import SwiftUI struct ContentView: View { let samples = ["foo", "bar"] var body: some View { NavigationSplitView { NavigationStack { sidebar } } detail: { NavigationStack { detail } } } var sidebar: some View { Sidebar(samples: samples) } var detail: some View { Text("Select a sample from the list.") } } struct Sidebar: View { @State private var isPresented = false let samples: [String] var body: some View { List { ForEach(samples, id: \.self) { sample in Text(sample) } } .navigationTitle("Foo") .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button("Info") { isPresented = true } .sheet(isPresented: $isPresented) { AboutView() } } } } } struct AboutView: View { @Environment(\.dismiss) private var dismiss: DismissAction var body: some View { NavigationStack { List { Text("Copyright © 2023 Foo. All Rights Reserved.") } .navigationTitle("About") .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .confirmationAction) { Button("Done") { dismiss() } } } } } }
Posted
by cht1995.
Last updated
.
Post not yet marked as solved
0 Replies
389 Views
Hello Community, Need your help/guidance please. Seeking LocationServices experts who can advise me whether my idea for a valuable add-on feature that I've been trying to add into my app for 2+ months is achievable or not given LocationServices limitations. The Feature: to enable users who would like to be automatically notified whenever they're within X meters from a store that provides them an exclusive discount BUT only when they choose to be notified. Instruction to enjoy the feature is by keeping app open in 'background state' (means opened and kept in background) but not when app is terminated state (completely closed). The state is important because I would like to give users the choice to only receive notifications when they choose to instead of all-time. That is to eliminate unnecessary power consumption fetching location updates constantly when user don't need them (example staying at home, at work, etc), but give them option when they go out. Ideal scenario (after opting in to enable 'Always'): user launches the app, keeps in background, go out shopping/dining/etc and enjoy convenience of being automatically notified whenever about Xmeters from a place that they have an exclusive offer for. Implemented conditions: API is called at fixed time interval whenever user is within about 10 meters from their last location, that is to limit checking only when there is certainty user is within the same place for sometime instead of just walking by (this currently works perfectly, using AccuracyBest), the challenge when user terminates app, LocationServices wakes up again and continues to fetch location updates constantly. The Ask: Is it technically possible that I configure app LocationServices to not wake-up with [AccuracyBest] when terminated but instead use only reduced accuracy (like 'significant location updates' or on 'AccuracyOne/ThreeKilometer')? Ideas/suggestions/recommendations would be much much appreciated
Posted
by Ramroum92.
Last updated
.
Post not yet marked as solved
1 Replies
442 Views
I would like to call a "GetMessages" API every 10 minutes while the app is not active or shutdown. if a message is returned, display the message as a local notification Will the background api run if the app is shut down? An example of this is when an email app shows a notification. Can they pull from their server while the app is not running or do they use the push notification service. I know that calendar events can be scheduled locally and for location changes, but I don't know if calling a api task with the app not running is possible.
Posted Last updated
.
Post not yet marked as solved
0 Replies
534 Views
I'm working on an in-house iOS app designed to help users accurately track their routes during trips. Currently, I've implemented a method to track users when the app is open in the background. However, I'm facing challenges, as the tracking stops when the device is locked for more than 10 minutes. I'm looking for a solution to continuously track a user's geolocation, even if the app is closed or not in use. Specifically, I want to ensure uninterrupted tracking, especially when the device is locked. Here are some key points: Current Method: I'm currently using the Core Location method and a combination of background tasks and a repeating timer to fetch the user's location and update a log for geolocation tracking when the app is open in the background. Issues Faced: The tracking stops when the device is locked for more than 10 minutes. This limitation impacts the accuracy of the route tracking during longer trips. Objective: My goal is to achieve continuous geolocation tracking, even when the app is closed or not actively used, to provide users with a seamless and accurate record of their routes. Platform: The app is developed for iOS using the .net maui platform, and I'm seeking solutions or suggestions that are compatible with the iOS .net maui environment. If anyone has experience or insights into achieving continuous geolocation tracking on iOS, especially when the app is not in use or the device is locked, I would greatly appreciate the assistance.
Posted Last updated
.
Post marked as solved
2 Replies
366 Views
Should we use absolute or calendar Date when scheduling background tasks? I would guess it doesn't matter how we construct Date but I wanted to double check since WWDC videos show both ways. I've experienced some instances where background tasks ran much later than expected, and while this is not surprising since iOS has many factors to consider when they allot background execution time, the times of execution seemed to line up with the hours change between Absolute and Calendar time. Or And I understand there is no guarantee that the system will run the background task exactly or even near the date requested. Thanks!
Posted Last updated
.
Post marked as solved
1 Replies
497 Views
I'am developing an iOS widget for my weather app, where the user can set the widget to "My location". This means the widget needs to be refreshed on location changes. Since a widget can't run a location manager in the background, apple tech support wrote that you have to setup a location manager in the main app and share the updated location data over App groups to the widget. This part works fine. I also managed to setup a location manager running in the background, but it uses too much battery and shows always the location indicator on top (blue bar) if the app is running, but I don't need this since its not a navigation app or something similar. How to configure a lightweight location manager running in the background? class WidgetLocationManager: NSObject, CLLocationManagerDelegate { static let shared: WidgetLocationManager = WidgetLocationManager() let manager = CLLocationManager() override init() { super.init() manager.delegate = self manager.desiredAccuracy = kCLLocationAccuracyKilometer manager.distanceFilter = 1000 manager.allowsBackgroundLocationUpdates = true manager.pausesLocationUpdatesAutomatically = false manager.activityType = .other manager.showsBackgroundLocationIndicator = false } func setupWidgetLocationManager() { manager.requestWhenInUseAuthorization() manager.startUpdatingLocation() manager.startMonitoringSignificantLocationChanges() } func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { if manager.authorizationStatus == .notDetermined || manager.authorizationStatus == .denied || manager.authorizationStatus == .restricted { manager.stopUpdatingLocation() manager.stopMonitoringSignificantLocationChanges() } if manager.authorizationStatus == .authorizedAlways || manager.authorizationStatus == .authorizedWhenInUse { manager.startUpdatingLocation() manager.startMonitoringSignificantLocationChanges() } } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let newestLocation = locations.last { UserDefaults(suiteName: "group.com.***")?.set(Double(newestLocation.coordinate.latitude), forKey: "newest_location_latitude") UserDefaults(suiteName: "group.com.***")?.set(Double(newestLocation.coordinate.longitude), forKey: "newest_location_longitude") UserDefaults(suiteName: "group.com.***")?.set(Double(newestLocation.altitude), forKey: "newest_location_altitude") WidgetCenter.shared.reloadAllTimelines() } } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { } } Capability for background modes location is set, also mandatory strings in info.plist for location privacy info.
Posted Last updated
.
Post not yet marked as solved
1 Replies
235 Views
Use case : We want to update our app content while the app is in the background. We want to download some json data from our backend server(HTTP GET) and update the content of the application so that next time when user launches the app he see updated content. We are using apple’s BackgroundTasks framework API, specially BGAppRefreshTask and BGProcessingTask. Pretty standard Problem → HTTP request via URLSession does not work. We register and schedule BGAppRefreshTask and BGProcessingTask. Our application is launched in the background by iOS. But when we make an HTTP request to a web server, we do not get any response callback. With default configuration, after making the request the response callback or the URLSessionDataDelegate methods are not called at all. (I also tried with google url. just to be sure the problem is not only with our backend) . Every thing works fine when I check entire flow while debugging and I am connected to Xcode and trigger a background launch by using this command e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.background_cloud_sync_apprefresh"] I am kind of stuck with this issue and have run out of ideas to try. So I am reaching out to expert here if you have faced any such issue on iOS. I have tried URLSession with callback as well as with URLSessionDataDelegate.
Posted Last updated
.
Post not yet marked as solved
1 Replies
415 Views
Hello fellow developers. I'm working on adding background tasks to my SwiftUI app and running into some issues. I have added the capabilities for background modes (fetch and processing) and the correct identifiers in "Permitted background task scheduler identifiers" When I test the background tasks on my device, it seems to only schedule the first task and ignoring the rest. I can run the first background task just fine with the command: e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"spotpricesRefresh"] But it only works for the first task since no other tasks seem to be scheduled. My code looks as below: .onChange(of: phase) { if (phase == .background) { scheduleSpotpricesRefresh() scheduleEmissionsRefresh() scheduleSourcesRefresh() BGTaskScheduler.shared.getPendingTaskRequests(completionHandler: { request in print("Pending task requests: \(request)") }) } } .backgroundTask(.appRefresh("spotpricesRefresh")) { await refreshSpotprices() } .backgroundTask(.appRefresh("emissionsRefresh")) { await refreshEmissions() } .backgroundTask(.appRefresh("sourcesRefresh")) { await refreshSources() } func scheduleSpotpricesRefresh() { let request = BGAppRefreshTaskRequest(identifier: "spotpricesRefresh") request.earliestBeginDate = Date(timeIntervalSinceNow: 60 * 60) do { try BGTaskScheduler.shared.submit(request) print("Scheduling spotprice refresh task") } catch { print("Could not schedule spotprices refresh: \(error)") } } func scheduleEmissionsRefresh() { let request = BGAppRefreshTaskRequest(identifier: "emissionsRefresh") request.earliestBeginDate = Date(timeIntervalSinceNow: 60 * 62) do { try BGTaskScheduler.shared.submit(request) print("Scheduling emissions refresh task") } catch { print("Could not schedule emissions refresh: \(error)") } } func scheduleSourcesRefresh() { let request = BGAppRefreshTaskRequest(identifier: "sourcesRefresh") request.earliestBeginDate = Date(timeIntervalSinceNow: 60 * 61) do { try BGTaskScheduler.shared.submit(request) print("Scheduling sources refresh task") } catch { print("Could not schedule sources refresh: \(error)") } } func refreshSpotprices() async { do { scheduleSpotpricesRefresh() ... } catch { print("Error occurred refreshing spotprices with error: \(error)") } } func refreshEmissions() async { do { scheduleEmissionsRefresh() ... } catch { print("Error occurred refreshing emissions with error: \(error)") } } func refreshSources() async { do { scheduleSourcesRefresh() ... } catch { print("Error occurred refreshing sources with error: \(error)") } } Here is the output when debugging the app: Scheduling spotprice refresh task Scheduling emissions refresh task Scheduling sources refresh task Pending task requests: [<BGAppRefreshTaskRequest: spotpricesRefresh, earliestBeginDate: 2023-11-14 10:24:51 +0000>] I hope someone can point me in the right direction. Thank you in advance. Best regards, Casper
Posted
by casperkc1.
Last updated
.
Post not yet marked as solved
1 Replies
296 Views
In the WWDC 2020 session "Background execution demystified", it was mentioned that the runtime of non-discretionary Background URL Sessions (using URLSession background transfer) is influenced mainly by factors such as the App Switcher and rate limits. Based on this information, I'm curious to know if there are specific factors that similarly affect the runtime of UIApplication.shared.beginBackgroundTask(). Are there any documented constraints or system behaviors that impact how long a background task initiated by this method can run? I would appreciate any documentation or insights that could help clarify this aspect of background task management in iOS.
Posted
by Seisyu.
Last updated
.
Post marked as solved
1 Replies
497 Views
Hello community, I am looking for information about how BGAppRefreshTasks behave in case a user has disabled the Background App Refresh for my app in the Settings app. Does disabling Background App Refresh for my app means, that my registered and schedules tasks will never run or will the system execute scheduled tasks when the app is in the foreground and has priority on system resources? My app is dependent on the data downloaded with an BGAppRefreshTask and I want to know if I have to implement alternative ways to download data, for example when the scene phase changes, if users restrict my app. Thanks for any information about this topic in advance!
Posted Last updated
.
Post not yet marked as solved
1 Replies
298 Views
Hello All, I have been having issues scheduling background tasks in iOS and was wondering if there is a repository of information for that type of task. Essentially, I just need to run a function (lets call it customFunction(), and it currently is a blank function that doesn't do anything, for testing purposes) once in a while (e.g., every 5min or so... it doesn't have to be precisely at 5min. The system can decide when to run it.) I am using the BackgroundTasks framework. The background task is being scheduled without a problem, but it's being denied execution by the system. bgRefresh-com.testing.scheduler:EECE08:[ {name: ApplicationPolicy, policyWeight: 50.000, response: {Decision: Can Proceed, Score: 0.35}} {name: DeviceActivityPolicy, policyWeight: 5.000, response: {Decision: Can Proceed, Score: 0.33}} ] sumScores:61.706667, denominator:97.540000, FinalDecision: Can Proceed FinalScore: 0.632629} 'bgRefresh-com.testing.scheduler:EECE08' CurrentScore: 0.632629, ThresholdScore: 0.805854 DecisionToRun:0 Does anyone have any feedback on the most important items to check when scheduling a background task? I can share code, if necessary.
Posted
by marcelops.
Last updated
.
Post not yet marked as solved
1 Replies
563 Views
I have a project that must upload data in background and keep data going even when the app is closed/terminated. So i have a background upload of data that should start/continue when the app is unloaded from memory (user force exit). In most of the cases after killing the app background upload resumes after some time (from few seconds to 10-20 mins) and data is successfully sent. However this does not always work even as expected. When the user kills the application, background uploading may terminate too with an error «Error Domain=NSURLErrorDomain Code=-999 "(null)" UserInfo={NSURLErrorBackgroundTaskCancelledReasonKey=0» After killing the app background upload may stop without finishing/throwing error and never produce any event, and when I open the application background upload does not resume. There is no error events and there is no pending/active background tasks either on my URLSession. Can they really vanish this way? In very rare cases I have encountered the problem that when background uploading in proccess (app is fully closed and when I launch the application a white screen appears (i see no splash screen, no main view), but I still can see logs that the background tasks is working actively. After the completion of data uploading the white screen does not go away, it is necessary to re-launcth the application to solve this problem. I note that these cases are not always encountered and most of the time background upload works correctly. But I'd would like to understand how to handle these problems and what can cause this weirdness. Do I get that right, so that after the user has force exited the application and it is unloaded from memory, even if a background upload task is launhed - we have no guarantee that the task will complete and the system won't kill the background task? I guess i have to act on my own, keep an eye on my tasks and restart them if they're got vanished/terminated? Is there any advices or good practices how to handle this best? And are there any strict limits on the amount of data that can be sent in background per task? P.S I do have these capabilities enabled: Background fetch &amp; Background processing.
Posted
by ElissP.
Last updated
.
Post not yet marked as solved
1 Replies
340 Views
I'm building a BGProcessingTask that may take more then 5 minutes to complete. The processing task runs on a Singleton object that can be accessed (or even started) when the app is on foreground. When the task expirationHandler is called, do i must finish my background work before calling task.setTaskCompleted(success: false)? I would like to have the background work suspended not cancelled. So when i reschedule another background processing task later or the app moves to foreground the same background task will continue. Is it ok practice? Will iOS might kill the background process (and the app) if not finished work before calling task.setTaskCompleted()? Or can i trust it will only get suspended and be able to resume later? Kind Regards
Posted
by Patz267.
Last updated
.