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

144 Posts
Sort by:
Post not yet marked as solved
1 Replies
379 Views
I have an app to communicate with a peripheral via L2CAP channel. Even I already enabled "Uses Bluetooth LE accessories" in "Background Mode", it still stop working when I lock the screen. Did some search and found these two posts: CBL2CAPChannel not responsive while app is backgrounded iOS Swift CoreBluetooth CBL2CAPChannel L2CAP Channel Oriented Connection Cannot Reconnect After Close From Central I am wondering if there are any solutions or work around about this. Based on the use case, I prefer to use L2CAP to transfer large data between two devices, so won't consider GATT.
Posted
by stonezhl.
Last updated
.
Post not yet marked as solved
0 Replies
428 Views
Hi, I'm relatively new to iOS development and kindly ask for some feedback on a strategy to achieve this desired behavior in my app. My Question: What would be the best strategy for sound effect playback when an app is in the background with precise timing? Is this even possible? Context: I created a basic countdown timer app (targeting iOS 17 with Swift/SwiftUI.). Countdown sessions can last up to 30-60 mins. When the timer is started it progresses through a series of sub-intervals and plays a short sound for each one. I used AVAudioPlayer and everything works fine when the app is in the foreground. I'm considering switching to AVAudioEngine b/c precise timing is very important and the AIs tell me this would have better precision. I'm already setting "App plays audio or streams audio/video using AirPlay" in my Plist, and have configured: AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: .mixWithOthers) Curiously, when testing on my iPhone 13 mini, sounds sometimes still play when the app is in the background, but not always. What I've considered: Background Tasks: Would they make any sense for this use-case? Seems like not if the allowed time is short & limited by the system. Pre-scheduling all Sounds: Not sure this would even work and seems like a lot of memory would be needed (could be hundreds of intervals). ActivityKit Alerts: works but with a ~50ms delay which is too long for my purposes. Pre-Render all SFX to 1 large audio file: Seems like a lot of work and processing time and probably not worth it. I hope there's a better solution. I'd really appreciate any feedback.
Posted
by hekuli.
Last updated
.
Post not yet marked as solved
0 Replies
307 Views
I'm trying to execute a background task following the Developer Documentation. This is my code import SwiftUI @main struct MyAppTest_Watch_AppApp: App { @Environment(\.scenePhase) var scenePhase let bs = BackgroundSession() @SceneBuilder var body: some Scene { WindowGroup { ContentView() }.backgroundTask(.appRefresh("prova")) { context in print("bg task") await scheduleTask() } .onChange(of: scenePhase) { phase in switch phase { case .active: print("\(#function) REPORTS - App change of scenePhase to ACTIVE") case .inactive: print("\(#function) REPORTS - App change of scenePhase Inactive") case .background: print("\(#function) REPORTS - App change of scenePhase Background") WKApplication.shared() .scheduleBackgroundRefresh( withPreferredDate: Date.init(timeIntervalSinceNow: 5 * 60.0), userInfo: "prova" as NSSecureCoding & NSObjectProtocol, scheduledCompletion: schedule) default: print("\(#function) REPORTS - App change of scenePhase Default") } } } func scheduleTask() async { bs.testSession() await WKApplication.shared() .scheduleBackgroundRefresh( withPreferredDate: Date.init(timeIntervalSinceNow: 5 * 60.0), userInfo: "prova" as NSSecureCoding & NSObjectProtocol, scheduledCompletion: schedule) } func schedule(error: Error?) { if error != nil { // Handle the scheduling error. fatalError("*** An error occurred while scheduling the background refresh task. ***") } print("Scheduled!") } } On the simulator the background refresh occurs correctly according to the preferred date and executes the background task, on the real watch it does not. I also set the app as complication in my watch face. The device I'm testing the app on is an Apple Watch Serie 7 with watchOS 10.3. Any idea?
Posted Last updated
.
Post not yet marked as solved
1 Replies
398 Views
Detecting New WiFi Connection + WiFi Details What I want to accomplish: The app, including when backgrounded or suspended, creates a local notification (assuming the app has permission for notifications) when there is a new WiFi network being used and ideally being able to execute some small code to customize the notification. This code would also have access to SSID info, security type, etc., so the sort of info in NEHotspotNetwork. A number of apps seem able to do this but I am having trouble replicating what they are doing. What I’ve looked at or tried: Looking at “TN3111: iOS Wi-Fi API overview” https://developer.apple.com/documentation/technotes/tn3111-ios-wifi-api-overview Navigate an internet hotspot (NEHotspotHelper) Doesn’t look like NEHotspotHelper would provide the above functionality for detecting changes while backgrounded and it seems to indicate that the special entitlement com.apple.developer.networking.HotspotHelper would not be granted for this use case anyway. Add an accessory to the user’s network (Wireless Accessory Configuration (WAC) or HomeKit) Doesn’t seem relevant to my use case Peer-to-peer networking Doesn’t seem relevant to my use case Location tracking I don’t want to know my user’s location and Lookout and Norton 360 (just two of many examples) don’t request or have location permissions (or request any permissions for that matter except notifications) and are still able to obtain the WiFi network info without it as well as detect changes in the background. Current Wi-Fi network NEHotspotNetwork .fetchCurrent(completionHandler:) So this is the most obvious since it returns the info I want but it requires the following permissions or configurations that neither Lookout or Norton 360 are requesting and also I don’t see how this API would trigger a backgrounded app to run, more for when your app is in the foreground and able to run already. From Apple docs: “This method produces a non-nil NEHotspotNetwork object only when the current network environment meets all four of the following critieria: The app is using the Core Location API and has user’s authorization to access precise location. The app used the NEHotspotConfiguration API to configure the current Wi-Fi network. The app has active VPN configurations installed. The app has an active NEDNSSettingsManager configuration installed. This method also requires the app to have the Access Wi-Fi Information Entitlement, and produces nil if the app lacks this entitlement.” Once again, apps that are able to do what I want don't seem to have location permissions, no VPN profile, no DNS config, no hotspot config.... Additional things I’ve considered that are not mentioned in the above: Using NWPathMonitor works for identifying a change, doesn’t trigger when app backgrounded and no access to SSID or other WiFi info. What am I missing? Is there some API that I totally missed? Thank you! Colin
Posted Last updated
.
Post not yet marked as solved
1 Replies
343 Views
What is the safest method for verify/register background tasks in an appliction? Apple docs state that trying to register a background task that’s already scheduled will crash the app. That is confirmed. Im looking to understand the best method for checking to see if a process is already registered to prevent the crash. Any help is appreciated.
Posted Last updated
.
Post not yet marked as solved
1 Replies
316 Views
How do you wake up an app without using push notification? I am developing a medical app which is isolated from the internet for cybersecurity/HIPAA reasons. When the iPhone is locked, I would like the app to launch, or return to the foreground, when the server notifies it that an event occurred. Is there a way implement this using Swift?
Posted
by NkMA.
Last updated
.
Post not yet marked as solved
1 Replies
330 Views
I want to start a shell script during the boot of a MacOS (14.2.1) machine. But the scripts is executed only when I log in, not directly after the system has started. I wrote a plist definition like this: > ls -l /Library/LaunchDaemons/com.foobar.justLog.plist -rw-r--r--@ 1 root wheel 397 Jan 25 21:06 /Library/LaunchDaemons/com.foobar.justLog.plist > cat /Library/LaunchDaemons/com.foobar.justLog.plist <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.foobar.justLog</string> <key>RunAtLoad</key> <true/> <key>Program</key> <string>/usr/local/bin/justLog.sh</string> </dict> </plist> > The referenced shell script looks like this: > ls -l /usr/local/bin/justLog.sh -rwxr-xr-x@ 1 root wheel 105 Jan 25 14:46 /usr/local/bin/justLog.sh > cat /usr/local/bin/justLog.sh #!/bin/bash while true ;do echo "Started script $0 as user $(whoami) in $PWD ($(date))" sleep 120 done > Then I shutdown the mac and restarted it at 21:46:40. I waited until 21:48:00 before I logged on with my default user. I was expecting my script to be run after the machine startet. But when I check the files in /var/log/com.apple.xpc.launchd I see that there are no entries from launchd during the initial boot. It looks like launchd does nothing before the first user logs in. That's not the behaviour I would expect from a script to be run when the system boots. > for i in 5 6 7 8 ;do echo "inspecting minute: 21:4$i"; grep "2024-01-25 21:4${i}:" /var/log/com.apple.xpc.launchd/launchd.log{.2,.1,} /var/log/* 2>/dev/null | wc -l ;done inspecting minute: 21:45 11747 inspecting minute: 21:46 0 inspecting minute: 21:47 0 inspecting minute: 21:48 21150 > Can anyone explain why my script is not executed before I log in?
Posted Last updated
.
Post not yet marked as solved
1 Replies
274 Views
Hello, I am currently working on an iOS application that relies on WebSocket connections for real-time data updates. As part of our application's functionality, we need to ensure that WebSocket connections continue to operate seamlessly when the iOS app is in the background or when the device is locked by the user. I am seeking clarification on the following points: WebSocket Connection in Background: Will WebSocket connections remain active and functional when the iOS app is in the background? If not, what are the recommended best practices or guidelines for maintaining WebSocket connections during background execution? WebSocket Connection when Device is Locked: How does WebSocket behave when the iOS device is locked by the user? Are there any specific considerations or configurations that need to be addressed to ensure the WebSocket connection persists when the device is locked? Alternate Solutions for Background Data Collection: If WebSocket connections are not intended to work in the background, are there alternative approaches or APIs that can be employed to collect real-time data while the app is in the background? Specifically, is there a recommended method to collect data from a WebSocket connection and store it locally in an SQLite database while the application is running in the background? Any insights or guidance you can provide on these matters?
Posted
by mayur c.
Last updated
.
Post not yet marked as solved
0 Replies
254 Views
I activate the conditions as follows Unexpected operation found. Details are below Conditions and configurations used in the testing "Background Modes" Capability with "Location updates" checked on added the info.plist keys: NSLocationAlwaysAndWhenInUseUsageDescription, NSLocationWhenInUseUsageDescription with description invoking startMonitoringSignificantLocationChanges using core location API invoking didUpdateLocations using core location API Using Background fetch (15 minutes) I just press the Home button without any gesture. A few hours after the app was stopped, didfinishlaunch, didenterBackground, background fetch, and didUpdateLocation code did not run, but the app started running again in the background from the point it was stopped. The wake-up time is random, and the app will freeze again within a few seconds of running again.(I took logs in all delegate functions related to the app life cycle in the AppDelegate file, but nothing was executed when the app was relaunched.) Is the above behavior normal? If it's normal, who wakes up the app? How do I prevent my app from restarting unexpectedly?
Posted
by h_susan.
Last updated
.
Post not yet marked as solved
1 Replies
406 Views
I asked a similar question a while back: https://developer.apple.com/forums/thread/730946 Since then I have a new Mac and new iPhone and so I now have the hardware to actually play with WeatherKit. I've worked my way past all the entitlements stuff and have been able to use and expand on online examples. Cool. Trouble is, nearly every example you can find uses code designed to update the UI as fresh weather data is fetched. My app currently uses background URL fetches to obtain weather data, make some calculations and take appropriate actions, all in the background. Updating the UI was a separate challenge. So which asynchronous tool is the right one for this? How can I quickly update my existing code to call WeatherKit instead of going to a weather site for a download? I currently use something like a download task session: let weatherTask = session.downloadTask (with: URL(string: urlString)!) weatherTask.taskDescription = "weather" weatherTask.resume() or a dataTask session: var request = URLRequest(url: url) request.httpMethod = "GET" request.addValue("text/html", forHTTPHeaderField: "Content-Type") let taskWeatherPOP = URLSession.shared.dataTask(with: request) { (data, response, error) in if error != nil { print("Error is \(String(describing: error))") } if let POPData = data, let report = String(data: POPData, encoding: String.Encoding.utf8) { if weatherReportPOP.contains("ServiceUnavailable") { print("A Weather POP report error") } else { weatherReportPOP = report } // Close the IF service unavailable } // Closes the IF weather data is not nil } // Close Task Weather taskWeatherPOP.resume()
Posted
by waynehend.
Last updated
.
Post not yet marked as solved
1 Replies
528 Views
i have an issue when handling silent push in my app when the user close the app, here is my native code which works like charm when the app in the foreground, background or terminated status from a short time from closing the app, and after long time from closing it (+30min) it will not work anymore, it make me confuse why it does not work and other messaging app like viber, whatsapp and messanger you can still receive messages and calls even you swipe the app and close it !! is there any thing must i add !! override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -&gt; Void) { Messaging.messaging().appDidReceiveMessage(userInfo) if Auth.auth().canHandleNotification(userInfo) { completionHandler(.noData) return } // sample notification for testing let content = UNMutableNotificationContent() content.title = "Hi there" content.body = "Just test" content.sound = UNNotificationSound.default let request = UNNotificationRequest(identifier: "helloNotification", content: content, trigger: nil) UNUserNotificationCenter.current().add(request) { (error) in if let error = error { print("Error adding notification request: \(error.localizedDescription)") } } // resent to dart side let controller: FlutterViewController = window?.rootViewController as! FlutterViewController let notificationChannel = FlutterMethodChannel(name: "notificationHandler", binaryMessenger: controller.binaryMessenger) var dataToSend: [String: Any] = [:] if let text = userInfo["text"] as? String { dataToSend["text"] = text } // Convert the dictionary to NSDictionary let nsDataToSend = NSDictionary(dictionary: dataToSend) // Pass the NSDictionary to Dart notificationChannel.invokeMethod("handleRemoteMessage", arguments: nsDataToSend) } i checked : background capabilities : remote notifs, background fetching, voip, background processing
Posted
by devops07.
Last updated
.
Post not yet marked as solved
2 Replies
316 Views
I activate the conditions as follows Unexpected operation found. Details are below Conditions and configurations used in the testing "Background Modes" Capability with "Location updates" checked on added the info.plist keys: NSLocationAlwaysAndWhenInUseUsageDescription, NSLocationWhenInUseUsageDescription with description invoking startMonitoringSignificantLocationChanges using core location API invoking didUpdateLocations using core location API Using Background fetch (15 minutes) I swipe the app to switch from foreground to background mode, and stop the app without deleting it in the switcher. A few hours after the app was stopped, didfinishlaunch, didenterBackground, background fetch, and didUpdateLocation code did not run, but the app started running again in the background from the point it was stopped. The wake-up time is random, and the app will freeze again within a few seconds of running again.(I took logs in all delegate functions related to the app life cycle in the AppDelegate file, but nothing was executed when the app was relaunched.) Is the above behavior normal? If it's normal, who wakes up the app? How do I prevent my app from restarting unexpectedly?
Posted
by h_susan.
Last updated
.
Post not yet marked as solved
12 Replies
427 Views
Is there a good explanation somewhere of where background task identifiers are registered and how to modify these? I have entered the "Permitted background task scheduler identifiers" into my xcode target, and it is replicated automatically in Info.plist. I can run the app (which registers the identifier), move it to background (which schedules the task), and then use the debugger to test the launch ("e -l objc -- (void)[[BGTaskScheduler sharedScheduler]..."). However, if I then go back and change the identifier string in the target, plist, and app code, the debugger no longer launches the app in background. It doesn't issue any errors, but just doesn't run it. The change I made to the name is to add an "x" at the end of the string. If I change it back in the target, plist, and app, it works again just fine.
Posted
by dlshap.
Last updated
.
Post not yet marked as solved
2 Replies
344 Views
As the title says. We have a pretty specific need for our app, and I have an idea of how to achieve it, but would like input on whether it's good practice or not. In communication apps such as Whatsapp or Discord, they need to send local notifications (and ideally update cached message data so it's fresh) anytime the user gets a new message. Conveniently for them, they control the backend, and so can just send out a silent push notification to the device(s) of user involved. In our case, we are creating a UI for someone else's backend, meaning we can't simply send a silent push on data change. What we were originally thinking was a sort of crowd-source involving a combination of silent push and background refresh, but refresh won't work if the user closes the app. I've read all the given reasons for this, and though I still disagree, there isn't anything we can do about it. So what I'm now thinking is that, at whatever interval (say 1-3hrs) some serverless function sends a silent push to every single client, which will wake them up to make a fetch and compare to the cached data and send a local notification if necessary. Downside here is it will likely incur some cost, and frankly it just feels kind of iffy as a solution, but I'm not sure what else we can do without controlling the backend API. Thoughts? Is there anything I'm missing? Any better ideas? Thanks in advance!
Posted
by mtroalson.
Last updated
.
Post not yet marked as solved
0 Replies
221 Views
Greetings all, I have installed 2 similar function apps (which are safe/signed e.t.c.) I run at different times, and both add items to the Login Items background section, the one is adding a background daemon and is only functioning when the switch is turned to on, while the other adds a PriviledgedHelperTool and can function even if the switch is turned to off, but if it is turned to on, but if I run this app then somehow the other breaks and can not function properly. So as a workaround I keep the PriviledgedHelperTool switch to off and only the other app's daemon switch to on so they can both operate whenever I want. My question has to do with the one that adds the PriviledgeHelperTool, and I wonder if this script contains any crucial information for the functioning of the according application. Though even if I deleted the PriviledgedHelperTool of it from the according folder, and launched the app, it seems it was not regenerated neither any notification shown up or so. Furthermore even if I removed the PriviledgedHelperTool the app seems to function properly, but I would like that thought to be confirmed by some community experts / developers here. I am on MacBook Air M1, macOS Sonoma 14.3 Developer Beta Thank you all in advance for your time. Best regards.
Posted Last updated
.
Post not yet marked as solved
3 Replies
477 Views
In ios17 and above, I can detect when swiftUI app goes into and out of background using: @Environment(\.scenePhase) private var phase ... .onChange(of: phase) { switch phase { case .background: print("entering background...") case .active: print("entering foreground...") default: break } } Is there a straightforward way to do this in SwiftUI for ios 16? I've found some examples using UIKit, but I am not that swift (sorry, couldn't resist) with that framework.
Posted
by dlshap.
Last updated
.
Post not yet marked as solved
3 Replies
404 Views
Hi There, I am trying to record a meeting and upload it to AWS server. The recording is in .m4a format and the upload request is a URLSession request. The following code works perfectly for recordings less than 15 mins. But then for greater recordings, it gets stuck Could you please help me out in this? func startRecording() { let audioURL = getAudioURL() let audioSettings = [ AVFormatIDKey: Int(kAudioFormatMPEG4AAC), AVSampleRateKey: 12000, AVNumberOfChannelsKey: 1, AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue ] do { audioRecorder = try AVAudioRecorder(url: audioURL, settings: audioSettings) audioRecorder.delegate = self audioRecorder.record() } catch { finishRecording(success: false) } } func uploadRecordedAudio{ let _ = videoURL.startAccessingSecurityScopedResource() let input = UploadVideoInput(signedUrl: signedUrlResponse, videoUrl: videoURL, fileExtension: "m4a") self.fileExtension = "m4a" uploadService.uploadFile(videoUrl: videoURL, input: input) videoURL.stopAccessingSecurityScopedResource() } func uploadFileWithMultipart(endPoint: UploadEndpoint) { var urlRequest: URLRequest urlRequest = endPoint.urlRequest uploadTask = URLSession.shared.uploadTask(withStreamedRequest: urlRequest) uploadTask?.delegate = self uploadTask?.resume() }
Posted
by snehal-a.
Last updated
.
Post not yet marked as solved
0 Replies
444 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
243 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
.