Hi,
I want to develop an application with service can discover neighbors devices bluetooth in background, this service can run even app was killed.
The scan of bluetooth start every 5 sec as service, and find Bluetooth device and can read data from BLE device.
It's possible with IOS?
any limitations?
Thank you
Regads,
Thuyet
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
131 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
I tried to make a background tasks action, however, it seemed not working at all! I can be able to register the bg fetch but cannot having a perform of bg fetch. Can anyone help me? I also add background modes in the capability.
Here's my code:
import BackgroundTasks
import UserNotifications
//BusArrNotification
@main
struct SGPublicTransportApp: App {
init() {
_ = BackgroundTaskHelper.shared
}
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
@Environment(\.scenePhase) private var scenePhase
@AppStorage("BookTime") private var BookedNotificationTime: String = ""
@AppStorage("specificBusService") private var specificBusService: String = ""
@AppStorage("specificBusStopCode") private var specificBusStopCode: String = ""
var body: some Scene {
WindowGroup {
NavigationStack {
ContentView()
}
}
.onChange(of: scenePhase) { phase in
switch phase {
case .active:
print("Active")
if !BookedNotificationTime.isEmpty {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let time = dateFormatter.date(from: BookedNotificationTime)
let diffs = Calendar.current.dateComponents([.minute, .second], from: Date(), to: time!)
if diffs.minute! <= 0 && diffs.second! <= 0 {
specificBusService = ""
specificBusStopCode = ""
BookedNotificationTime = ""
}
}
case .background:
print("Background")
case .inactive:
print("Inactive")
@unknown default: break
}
}
.backgroundTask(.appRefresh("BusArrNotification")) { context in
// Perform the background task here.
await BackgroundTaskHelper.shared.scheduleBackgroundAppRefresh()
// let _ = await BackgroundTaskHelper.shared.performBackgroundRefresh()
print("HELLLO")
}
}
}
class BackgroundTaskHelper {
static let shared = BackgroundTaskHelper()
@ObservedObject var busDataService = BusDataService()
private init() {
// BGTaskScheduler.shared.register(forTaskWithIdentifier: "BusArrNotification", using: nil) { task in
// self.handleAppRefresh(task: task as! BGAppRefreshTask)
// }
}
func handleAppRefresh(task: BGAppRefreshTask) {
scheduleBackgroundAppRefresh()
task.expirationHandler = {
// Handle the expiration of the background task
}
// Perform the task
let isSuccess = performBackgroundRefresh()
if isSuccess {
task.setTaskCompleted(success: true)
} else {
task.setTaskCompleted(success: false)
}
}
func performBackgroundRefresh() -> Bool {
// Implement your background refresh logic here
busDataService.fetchBusData()
print("*** Background refresh performed! ***")
return true
}
func scheduleBackgroundAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: "BusArrNotification")
request.earliestBeginDate = Date(timeIntervalSinceNow: 10) // 15 minutes from now
do {
try BGTaskScheduler.shared.submit(request)
print("*** Scheduled! ***")
} catch {
print("*** An error occurred while scheduling the background refresh task: \(error) ***")
}
}
}
Good afternoon! I am working on an app which requires the app to be opened in response to a push notification from a background state. As it stands:
The app is running in the background
The app has a static widget on the homepage
The app has a dynamic widget with a live activity which is being updated from the backend
The dynamic widget is firing an event which the static widget is listening for
The static widget is programatically calling an AppIntent which tries to open the parent app
Is this possible? Is there a better approach which would work?
We are looking for a way to open the app from the background with the users permission. Appreciate any guidance on the issue
Hello,
I am currently developing an iOS application using SensorKit. I encountered an issue when attempting to fetch SensorKit data in the background using background tasks (appRefresh, processing). The following error occurs:
In the delegate function func sensorReader(_ reader: SRSensorReader, fetching fetchRequest: SRFetchRequest, failedWithError error: any Error) {}, I receive the error:
SRErrorDataInaccessible.
In code specific manner:
start and handle background fetch (appRefresh)
func handleAppRefreshTask(task: BGAppRefreshTask) {
logger.logWithServer(level: .default, message: "background fetch start", category: String(describing: BackgroundTaskManager.self))
scheduleBackgroundFetch()
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
let fetchOperation = FetchOperation()
queue.addOperation(fetchOperation)
task.expirationHandler = {
self.logger.logWithServer(level: .error, message: "background fetch expirated", category: String(describing: BackgroundTaskManager.self))
queue.cancelAllOperations()
}
fetchOperation.completionBlock = {
task.setTaskCompleted(success: !fetchOperation.isCancelled)
}
}
Background fetch operation class
class FetchOperation: Operation {
override func main() {
guard !isCancelled else { return }
Task {
// this function will execute fetch request for all user allowed sensorReader, 'func fetch(_ request: SRFetchRequest)'
await SensorkitManager.shared.startFetchAndUpload()
}
}
}
I have the following questions:
Is it possible to fetch SensorKit data in the background?
If it is possible, why does the above error occur?
If it is possible, could you provide the solution code and the correct workflow to avoid this error?
Thank you.
We are currently developing an application that allows Bluetooth connection to hardware devices as well as collecting user health information. When the user is using a device connected via Bluetooth, we can get information from that device and store it via API.
We currently want to create a background task that will get device information via Bluetooth every 10 seconds and send it. It will run even when the iPhone is in sleep mode. I have tried many ways, but these tasks will be closed after less than 1 minute when the user sleeps. I don't know if Apple has a separate mechanism for this job or is there a way to implement this feature.
Hello.
I have a few questions about Location Push Service and Screentime Family controls.
Do Location Push Service and Screentime Family controls require permission to be tested with development builds?
Will my application for permission to test be approved?
How long does it take to receive results if I apply for permission?
Is it possible to use the functionality of the Screentime api in LocationPushServiceExtention?
Is it possible to control remotely even if I apply for Screen time API's Family Controls permission as an individual? (ex. Change Screen time settings by push from server)
Information is needed to plan an app that includes both functions.
Thank you
We are currently developing an application that runs in the background and continuously scans for other nearby devices via peer-to-peer networking. Generally, the high-level goals are:
Scan for nearby devices while the app is in the background state. We only need to discover devices that are also running our app.
Read a small token of data from each peer device found (no need for full-duplex connection)
Submit this token to our server via a background network request
On Android we have demonstrated this functionality using both Bluetooth LE and WifiDirect service discovery, and background operation is easily achieved with Android services. We are currently trying to expand our application to support cross-platform compatibility between IOS and Android, including IOS<-->IOS and IOS<-->Android discovery (in the background). Is there a way to achieve this desired functionality on IOS?
I have a Companion Watch App for my iPhone App and communicate via the messages and applicationContext between the watch and the phone. If I start an Event at my iPhone and my watch is turned on the extendedRuntimeSession starts as it should. But as soon as my Watches Display is off or Im not in the App I can't start the extendedRuntimeSession, even though I receive it trough the applicationContext and I get the following errorMessage when trying to start the session in the background.
-[CSLSSessionService startSession:completionWithExpirationDate:]_block_invoke session A76273B7-3E01-4333-920C-0614C1FAC5B0 encountered error Error Domain=com.apple.CarouselServices.SessionErrorDomain Code=12 "app not in required app state" UserInfo={NSLocalizedDescription=app not in required app state}
Is Running is true
Timer started/continuend
-[SPApplicationDelegate appBeginWorkout:]_block_invoke:1334: Asked to start a workout, but WKExtensionDelegate <SwiftUI.ExtensionDelegate: 0x15d7c500> doesn't implement handleWorkoutConfiguration:
Extended runtime session invalidated with reason: WKExtendedRuntimeSessionInvalidationReason(rawValue: -1), error: Optional(Error Domain=WKExtendedRuntimeSessionErrorDomain Code=3 "The app must be active and before applicationWillResignActive to start or schedule a WKExtendedRuntimeSession." UserInfo={NSLocalizedDescription=The app must be active and before applicationWillResignActive to start or schedule a WKExtendedRuntimeSession..})
I control and manage my session like this:
class WatchViewModel: NSObject, ObservableObject {
static let shared = WatchViewModel()
var session: WCSession
var extendedRuntimeSessionManager: ExtendedRuntimeSessionManager
var lastMessage: [String: Any] = ["method": "none"]
@Published var iOSIsReachable = false
@Published var dataFromMessages = DataFromMessages()
@Published var flextailCoordinates: FlextailCoordinates?
init(session: WCSession = .default, extendedRuntimeSessionManager: ExtendedRuntimeSessionManager = ExtendedRuntimeSessionManager()) {
NSLog("init start")
self.session = session
self.extendedRuntimeSessionManager = extendedRuntimeSessionManager
super.init()
self.session.delegate = self
session.activate()
NSLog("init done")
}
}
class ExtendedRuntimeSessionManager: NSObject, WKExtendedRuntimeSessionDelegate, ObservableObject{
var extendedRuntimeSession: WKExtendedRuntimeSession?
@Published var sessionIsActive = false
override init() {
super.init()
setupExtendedRuntimeSession()
}
func setupExtendedRuntimeSession() {
extendedRuntimeSession = WKExtendedRuntimeSession()
extendedRuntimeSession?.delegate = self
}
func startExtendedRuntimeSession() {
if sessionIsActive == false{
extendedRuntimeSession?.start()
} else{
print("Already running extendedRuntimeSession")
}
}
func stopExtendedRuntimeSession() {
extendedRuntimeSession?.invalidate()
sessionIsActive = false
setupExtendedRuntimeSession()
}
// WKExtendedRuntimeSessionDelegate methods
func extendedRuntimeSessionDidStart(_ extendedRuntimeSession: WKExtendedRuntimeSession) {
print("Extended runtime session started")
sessionIsActive = true
}
func extendedRuntimeSessionWillExpire(_ extendedRuntimeSession: WKExtendedRuntimeSession) {
print("Extended runtime session will expire soon")
}
func extendedRuntimeSession(_ extendedRuntimeSession: WKExtendedRuntimeSession, didInvalidateWith reason: WKExtendedRuntimeSessionInvalidationReason, error: Error?) {
print("Extended runtime session invalidated with reason: \(reason), error: \(String(describing: error))")
sessionIsActive = false
setupExtendedRuntimeSession()
}
}
I tried sending it through the applicationContext but that didn't work, even though the message gets received and parsed as I want. The error specifically seems to be in the starting of an extendedRuntimeSession in the background.
Hello everyone, I am spending a lot of work with an application, this is based on obtaining the information from the official USCIS website, the user enters their receipt and it verifies on the USCIS website if that receipt exists, once verified it returns the information of that receipt, which I save in coredata so that the user only has to press a button to reload that information, all this is perfect, the problem is that I want the cases to be updated in the background so that the user does not have to be Entering the application, it is responsible for updating only the cases and if there was a change in your case, showing a notification to the user, I have the function of updating the cases so that when it detects a change in the database it notifies the change to the user. user, I have read the documentation but Background Task, Fetch etc. does work for me if the application is in the background that is, not closed, but when it is closed completely it does not update these cases, I have read in groups and with silent notifications to lift the application but I don't want to depend on a server, is there a method to call the function to update the cases when the application is closed (SwiftUI - Swift for iOS I am programming)
After integration with MusicKit, I have an issue with Watchdog. The crash log point on this stack trace:
ProcessState: Running
WatchdogEvent: scene-update
WatchdogVisibility: Background
WatchdogCPUStatistics: (
"Elapsed total CPU time (seconds): 72.560 (user 49.970, system 22.590), 39% CPU",
"Elapsed application CPU time (seconds): 11.270, 6% CPU"
) reportType:CrashLog maxTerminationResistance:Interactive>
Triggered by Thread: 0
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x1dfa74808 mach_msg2_trap + 8
1 libsystem_kernel.dylib 0x1dfa78008 mach_msg2_internal + 80
2 libsystem_kernel.dylib 0x1dfa77f20 mach_msg_overwrite + 436
3 libsystem_kernel.dylib 0x1dfa77d60 mach_msg + 24
4 libdispatch.dylib 0x19e884b18 _dispatch_mach_send_and_wait_for_reply + 544
5 libdispatch.dylib 0x19e884eb8 dispatch_mach_send_with_result_and_wait_for_reply + 60
6 libxpc.dylib 0x1f386bac8 xpc_connection_send_message_with_reply_sync + 264
7 Foundation 0x195853998 __NSXPCCONNECTION_IS_WAITING_FOR_A_SYNCHRONOUS_REPLY__ + 16
8 Foundation 0x195850004 -[NSXPCConnection _sendInvocation:orArguments:count:methodSignature:selector:withProxy:] + 2160
9 Foundation 0x1958c820c -[NSXPCConnection _sendSelector:withProxy:arg1:] + 116
10 Foundation 0x1958c7e80 _NSXPCDistantObjectSimpleMessageSend1 + 60
11 MediaPlayer 0x1a8c0ff24 -[MPMusicPlayerController _validateServer] + 128
12 MediaPlayer 0x1a8c3f4f8 -[MPMusicPlayerApplicationController _establishConnectionIfNeeded] + 2144
13 MediaPlayer 0x1a8c0fbb8 -[MPMusicPlayerController onServer:] + 52
14 MediaPlayer 0x1a8c0ec94 -[MPMusicPlayerController _nowPlaying] + 372
15 MediaPlayer 0x1a8c161a4 -[MPMusicPlayerController nowPlayingItem] + 24
16 MusicKit 0x213253e78 -[MusicKit_SoftLinking_MPMusicPlayerController nowPlayingItem] + 24
17 MusicKit 0x2136ec1bc 0x2131b9000 + 5452220
18 MusicKit 0x2136ec70c 0x2131b9000 + 5453580
19 MusicKit 0x2136ed839 0x2131b9000 + 5457977
20 MusicKit 0x213221c65 0x2131b9000 + 429157
21 MusicKit 0x21354b741 0x2131b9000 + 3745601
22 libswift_Concurrency.dylib 0x1a1d0e775 completeTaskWithClosure(swift::AsyncContext*, swift::SwiftError*) + 1
According to the log - the app is in the background and the stack trace has only MusicKit. How could we disable or avoid this activity to avoid the Watchdog issue?
Music app stops playing when switching to the background
In apps that play music or music files, if you move to the home screen or run another app while the app is running, the music playback stops.
Our app does not have the code to stop playing when switching to the background.
We are guessing that some people experience this and others do not.
We usually guide users to reboot their devices and try again.
How can this phenomenon be improved in the code?
Or is this a bug or error in the OS?
After the 'IdentificationAccepted' message, I sent 'RequestAppLaunch' with 'AppBundleID' and 'AppLaunchMethod'.
However, the app isn't launched by the external accessory.
I checked it with ATS and saw the error message:
'Error: accessory sent a message that the Apple device did not acknowledge during identification. Section: Section 28.2.2 Sent/Received iAP2 Control Session Messages. Source: Accessory Interface Specification R42.'
Do you have any idea how to fix it?
Thank you in advance.
Let's say I have a Task that I want to extend into the background with beginBackgroundTask(expirationHandler:). Furthermore, I'd like to leverage cooperative cancelation of subtasks when responding to the expiration handler. Unfortunately, the expirationHandler: closure parameter is not async, so I'm unable to do something like:
actor MyTaskManagerOne {
var backgroundID = UIBackgroundTaskIdentifier.invalid
func start() {
Task {
let doTheWorkTask = Task {
await self.doTheWork()
}
backgroundID = await UIApplication.shared.beginBackgroundTask {
doTheWorkTask.cancel()
// next line: compile error, since not an async context
await doTheWorkTask.value // ensure work finishes up
// next line: generates MainActor compilation warnings despite docs allowing it
UIApplication.shared.endBackgroundTask(self.backgroundID)
}
await doTheWorkTask.value
}
}
func doTheWork() async {}
}
So instead, I think I have to do something like this. It, however, generates runtime warnings, since I'm not directly calling endBackgroundTask(_:) at the end of the expirationHandler:
actor MyTaskManagerTwo {
var backgroundID = UIBackgroundTaskIdentifier.invalid
func start() {
Task {
let doTheWorkTask = Task {
await self.doTheWork()
}
backgroundID = await UIApplication.shared.beginBackgroundTask {
doTheWorkTask.cancel()
// 1. not calling endBackgroundTask here generates runtime warnings
}
await doTheWorkTask.value
// 2. even though endBackgroundTask gets called
// here (as long as my cooperative cancellation
// implementations abort quickly in `doTheWork()`)
await UIApplication.shared.endBackgroundTask(self.backgroundID)
}
}
func doTheWork() async {}
}
As best I can tell, the MyTaskManagerTwo actor works and does not cause a watchdog termination (as long as cancellation is sufficiently fast). It is, however, producing the following runtime warning:
Background task still not ended after expiration handlers were called: <_UIBackgroundTaskInfo: 0x302753840>: taskID = 2, taskName = Called by libswift_Concurrency.dylib, from <redacted>, creationTime = 9674 (elapsed = 28). This app will likely be terminated by the system. Call UIApplication.endBackgroundTask(_:) to avoid this.
Is the runtime warning ok to ignore in this case?
I have a .app file that I want to run as a daemon. Now there are two ways of running .app as a daemon/agent in macOS.
using .app file : I can specify this in the daemon plist as:
<key>ProgramArguments</key>
<array>
<string>/usr/bin/open</string>
<string>/Applications/myApp.app</string>
</array>
using unix exe within .app file
<key>ProgramArguments</key>
<array>
<string>myApp.app/Content/MacOS/MyApp</string>
</array>
Basically I wanted to know what is the Apple recommendation on how we should be creating daemon plist.
For point 2, is it appropriate to use the unix executable within bundle?Will it not cause any issue in the running application?
Is will be helpful if there is some apple documentation to support this.
I am working on an app which is capturing photos and uploading them to a server.
I have followed the URLSession configuration to properly support background transfers. However, I am now noticing that my photos are uploading way slower, even when the user has the app open and is interacting with the app. This is undesirable because the changes need to be reflected in real time to the server when the user is active in the app.
Previously, when I was just using URLSession.shared.uploadTask with a completion handler, the photos uploaded right away in a matter of 1-2 seconds.
Now it is taking 3-4 minutes per photo to upload. The photos are roughly 3mb in size each. I have tried setting the isDiscretionary property explicitly to false to no avail.
Sometimes the users are without internet connection, which is why I wanted to use the background session (so that the uploads can be automatically retried by the system when the user connects back to the internet)
So, in summary, I want the functionality of the background uploading (and to let the system retry when the user transitions from offline to online) however I also need realtime uploading when the user is interacting with the app.
What is the preferred way to solve this problem?
I have developed a backup application in Java. In it, users can configure whether they want it to autostart or not. If they do, a plist file is being written to ~/Library/LaunchAgents so that my app starts at login. This works perfectly so far.
I've not submitted it to the Mac App Store. But for that, it needed to be sandboxed. And with that, I had to add a "com.apple.security.temporary-exception.files.home-relative-path.read-write=/Library/LaunchAgents/" to my entitlements so that the plist file could still be written to ~/Library/LaunchAgents. However, they do not approve this.
Is there another solution to launch my application at login?
Must work with sandbox-mode
Must work from Java/Shell/... (I found "SMAppService", but this seems only available in Swift/Objective-C)
Hello, I would like to implement the function of unsubscribe FCM topics that I was subscribing to when I received a specific push from the server.
It was implemented through "willPresent" when the app was running, but I don't know how to do it when the app is not running.
I activated the 'Background fetch' and 'Remote Notifications' options for now.
const message = {
notification: {
title: 'FCM Topic UnSubscribe',
body: 'TestTestTest',
},
data: {
payload: JSON.stringify(payloadJson)
},
apns: {
payload: {
aps: {
sound: 'default',
'mutable-content': 1,
'content-available': 1
}
}
},
topic: 'unsubscribe_topic',
};
Test node code
Payload contains the type of topic you want to unsubscribe from.
And I added a function to receive push from didReceiveRemoteNotification and handle logic.
But this doesn't work.
Does Remote Notification (content-available) not work in iOS's Not running and Suspended state??
I'm also using the Notification Service Extension, is this related to it?
Hi,
We are developing an app for secure printing using a BLE RFID reader.
What we'd like to accomplish is the ability for a user to walk away from the printer (BLE RFID reader) for any time period (10 mins, 1 hour, or 3 hours) with the app still running background mode but out of range from the RFID reader, and walks back to the printer (BLE RFID reader) and be able to connect to the reader thus enabling printing.
We've noticed that when the phone is out of range from the BLE reader and phone auto-locks, the background scanning process is terminated after a few minutes.
Is there a way to accomplish the above? Any help is appreciated.
Thank you,
Marlon
We've got a non-sandboxed app with a built-in daemon that does some root-privileged things for us on occasion. We're using the newest SMAppService APIs, using NSXPCConnections for communications, and generally things work as expected. The daemon is set up to terminate when the parent app terminates.
Our app also has (and uses the daemon for) a self-update feature. Once the new app is downloaded, the daemon takes over, replaces the app in-place, terminates the old app and launches the new one.
However, after this update, the daemon no longer works.
Any other build & launch of the app will silently fail when trying to talk to the daemon. The XPC connection can be constructed as usual, no errors, the process goes along like it should app-side, but the daemon never actually launches and never responds.
I can imagine there could be a few rules being broken here with the self-update and the built-in daemon, but what would they be and how can we work within the rules?
Hello,
I have an iOS app and a companion watchOS app. Users record a workout on Apple Watch, the data for which is then transferred using both Watch Connectivity and Core Data + CloudKit (NSPersistentCloudKitContainer) to their iPhone, where it is processed and displayed.
As users are recording the workout on their Apple Watch, when they finish and the transfer begins, their iPhone is often not reachable to immediately send the data using Watch Connectivity and they have no network connection (cellular or Wi-Fi).
With Watch Connectivity I use transferFile from WCSession, which queues the file for transfer. With Core Data + Cloudkit I save the data and the export is queued.
An undetermined amount of time may pass until the user returns to their iPhone or connects to Wi-Fi and most of the time neither of the transfer methods actually transfers the data until the user opens the watchOS app into the foreground, at which point the transfer happens immediately for both methods.
I've tried a number of things already, without success, such as:
Using sendMessage from WCSession to send an immediate message to the watchOS app when the iOS app returns to the foreground to try and wake the watchOS app up so it can complete the data transfer.
On the watchOS app, after attempting to transfer the data, using downloadTask from URLSession to queue a background task to download something, in the hope that it would wake the watchOS app when network connectivity was restored and enable it to complete the data transfer.
On the watchOS app, instead of saving the data using NSPersistentCloudKitContainer, using CKRecord and CKDatabase directly to save the data using userInitiated as the quality of service, in the hope that it would be exported once network connectivity was restored.
Is there a way to trigger the watchOS app to transfer the data using Watch Connectivity or Core Data + CloudKit in the background when reachabillity or network connectivity is restored, even if the app may have been suspended by watchOS?
Many Thanks,
Alex