Background Tasks

RSS for tag

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

Posts under Background Tasks tag

129 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Running Bluetooth (BLE) tasks in background, with React Native
Currently working on an emergency app paired with a BLE device, and the desired use case is: When the device is triggered, it sends your location to your emergency contacts an API we've built. This flow works while the app is open, but we need things to obviously work while in background (while the phone is sleeping as well, of course, for emergency contexts) From what I've researched and understood, background fetches don't really work, because the intervals are a maximum of about 15 minutes, and iOS will make them less frequent based on app usage, and that window in an emergency situation isn't good enough. Having read around, I've bumped into a couple resources that suggest background bluetooth processing is possible, if I listen for a particular service being advertised, but I haven't been able to make things work so far. I wanted some help on this.
2
0
758
Feb ’24
Playing Timed Sound Effects in Background
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.
0
0
585
Feb ’24
L2CAP channel doesn't work in background
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.
1
0
499
Feb ’24
handleBackgroundTasks not called on apple watch but only on simulator
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?
0
0
384
Feb ’24
Monitoring for network changes while backgrounded or suspended
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
1
0
619
Feb ’24
My launchd scripts are not run after boot but after login
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?
1
0
403
Jan ’24
URLSessionWebSocketTask + WebSocket+ Persistent socket connection even in background
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?
1
0
347
Jan ’24
Unexpected restart of app into background
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?
0
0
304
Jan ’24
Handle background notification in terminated status app
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
1
0
930
Jan ’24
Need strategy for using WeatherKit in the background
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()
1
0
545
Jan ’24
Periodic Background Update (including force-quit)
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!
2
0
404
Jan ’24
PriviledgedHelperTools - Are they mandatory?
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.
1
0
269
Jan ’24
Unexpected restart of app into background
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?
2
0
377
Jan ’24
Detect foreground/background change
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.
5
0
761
Jan ’24
SwiftUI Background Tasks iOS 17
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() } } }
0
0
559
Jan ’24
centralManager does not get the changed advertisementData[CBAdvertisementDataLocalNameKey] when the screen is off
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?
0
0
288
Jan ’24
Unable to upload recording of more than 15 mins to AWS server
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() }
3
0
468
Jan ’24
Can't change background task identifier
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.
12
0
603
Jan ’24