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

Background Tasks Resources
General: DevForums tag: Background Tasks Background Tasks framework documentation UIApplication background tasks documentation ProcessInfo expiring activity documentation watchOS background execution documentation WWDC 2020 Session 10063 Background execution demystified — This is critical resource. Watch it! WWDC 2022 Session 10142 Efficiency awaits: Background tasks in SwiftUI iOS Background Execution Limits DevForums post UIApplication Background Task Notes DevForums post Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com"
0
0
2.4k
Jun ’22
Moving to Fewer, Larger Transfers
Note Much of this content has been rolled into URL Loading System documentation, but I’m leaving this doc here for my own reference. URLSession background sessions are optimised for transferring a small number of large resources. Moreover, it’s best if the transfer is resumable. This design makes the best use of client device resources and the available network bandwidth. If your app runs a lot of tasks in a background session, you should rethink its design. Below you’ll find a number of options you might consider. Most of these options require server-side support. If your server does not have this support, and you can’t add it — perhaps you’re writing a client app for a server you don’t control — you won’t be able to implement these options directly. In that case consider creating your own server that sits between your app and the final server and implements the necessary smarts required to optimise your app’s network usage. If that’s not possible, a final option is to not use a background session but instead take advantage of the BackgroundTasks framework. See BackgroundTasks Framework, below. Basics The basic strategy here is to have the sender (the server for a download, your app for an upload) pack the data into some sort of archive, transfer that archive over the network, and then have the receiver unpack it. There are, however, a number of complications, as described in the subsequent sections. Archive Format The obvious choices for the archive format are zip and tar. macOS has lots of options for handling these formats but none of that support is present on iOS (r. 22151959). OTOH, it’s easy to find third-party libraries to fill in this gap. Incremental Transfers It’s common to have a corpus of data at one end of the connection that you need to replicate at the other. If the data is large, you don’t want to transfer the whole thing every time there’s an update. Consider using the following strategies to deal with this: Catalogue diff — In this approach the receiver first downloads a catalogue from the sender, then diffs its current state against that catalogue, then requests all the things that are missing. Alternatively, the receiver passes a catalogue of what it has to the sender, at which point the sender does the diff and returns the things that are missing. The critical part is that, once the diff has been done, all of the missing resources are transferred in a single archive. The biggest drawback here is resume. If the sender is working with lots of different receivers, each of which has their own unique needs, the sender must keep a lot of unique archives around so it can resume a failed transfer. This can be a serious headache. Versions — In this approach you manage changes to the data as separate versions. The receiver passes the version number it has to the sender, at which point the sender knows exactly what data the receiver needs. This approach requires a bit more structure but it does avoid the above-mentioned problem with resume. The sender only needs to maintain a limited number of version diffs. In fact, you can balance the number of diffs against your desire to reduce network usage: Maintaining a lot of diffs means that you only have to transfer exactly what the receiver needs, while maintaining fewer diffs makes for a simpler server at the cost of a less efficient use of the network. Download versus Upload The discussion so far has applied equally to both downloads and uploads. Historically, however, there was one key difference: URLSession did not support resumable uploads. IMPORTANT Starting with iOS 17, URLSession supports resumable uploads. See WWDC 2023 Session 10006 Build robust and resumable file transfers for the details. The rest of this section assumes that you don’t have access to that support, either because you’re working on an older system or because the server you’re uploading to doesn’t support this feature. When doing a non-resumable upload you have to balance the number of tasks you submit to the session against the negative effects of a transfer failing. For example, if you do a single large upload then it’s annoying if the transfer fails when it’s 99% complete. On the other hand, if you do lots of tiny uploads, you’re working against the URLSession background session design. It is possible to support resumable uploads with sufficient server-side support. For example, you could implement an algorithm like this: Run an initial request to allocate an upload ID. Start the upload with that upload ID. If it completes successfully, you’re done. If it fails, make a request with the upload ID to find out how much the server received. Start a new upload for the remaining data. Indeed, this is kinda how the built-in resumable upload support works. If you’re going to implement something like this, it’s best to implement that protocol. (r. 22323347) BackgroundTasks Framework If you’re unable to use an URLSession background session effectively, you do have an alternative, namely, combining a standard session with the BackgroundTasks framework, and specifically the BGProcessingTaskRequest. This allows you to request extended processing time from the system. Once you’ve been granted that time, use it to run your many small network requests in a standard session. The main drawback to this approach is latency: The system may not grant your request for many hours. Indeed, it’s common for these requests to run overnight, once the user has connected their device to a power source. Background Assets Framework If you’re using URLSession to download assets for your app or game, check out the Background Assets framework. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Revision History 2023-09-27 Added information about the new resumable upload support. Added the Background Assets Framework section. Made significant editorial changes. 2022-01-31 Fixed the formatting and tags. Added a link to the official docs. 2018-03-24 Added the BackgroundTasks Framework section. Other editorial changes. 2015-08-18 First written.
0
0
5.3k
Sep ’23
Sending data to server in background mode(killed app state)
Hi guys, I got one issue about sending data with interval 1000 seconds to the server, while the app has been killed by user. I found the relevant document about app in background mode. https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html but I checked the document, it seems there is no way to use NSTimer inside the block of beginBackgroundTaskWithName... function. NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector: #selector(AppDelegate.handleTimer), userInfo: nil, repeats: true) Question: How to consistently send data to server with interval time while app has been terminated? Thank you, e
8
0
9.3k
Jun ’23
Silent Notification
I am trying to implement silent push notification in my application where I need to update some data in the server when silent notification comes. I am using Pushkit and it uses VoIP certificate for silent push notification but the app has been rejectd by Apple saying that "I can't use VoIP" certificate. It seems that apple has rejected it as I don't have any VoIP call functionality in my app. In that case how can I implement silent push notification so that my app gets activated even if it is not runnning(not even in the background) and I can update the server?
4
0
4k
Jul ’23
BGProcessingTask starts only if connected to power even if requiresExternalPower is NO
I setup a BGProcessingTask that do some work with the db and at the end sends an email. I've notice that, even if I set requiresExternalPower to false the task runs only when the device is connected to the power cable. I've tested setting the repeating time every 10 minutes. If the power cable is disconnected the task isn't launhed anuymore. After I attach the cable, waiting some minutes it restarts.
7
0
2.1k
Oct ’23
Background fetch after app is force-quit
Hello! Can someone please confirm whether or not an app will trigger background fetch after it has been force-quit by the user? Currently my app works performs background fetches correctly when it has been backgrounded, but after force-quitting the app it stops fetching. Specifically I am referring to scheduled background fetches, not fetches initiated by notifications - although I am interested to know if that would be an alternative. I've tried searching online and there's a lot of confusing and contradictory information about this - including old Apple documentation that explicitly says it will not launch, however that documentation has since been removed. The new documentation does not explicitly mention the force-quit scenario. Can anyone please confirm? Thanks!
12
2
5.1k
Sep ’23
CloudKit and Background tasks
Hi. Didn't find the answer in the documentation. Are CloudKit procedures executables in background tasks ? I'm trying to do : "[privateDatabase fetchRecordWithID:myMasterRecordID completionHandler:^(CKRecord *myMasterRecord, NSError *error) { ... }]" but it returns a record only when the app is active. In background task, it does nothing and waits until app is active. Thanks for you answer. Best Claude
1
0
700
Oct ’23
iOS Background Execution Limits
I regularly see questions, both here on DevForums and in my Day Job™ at DTS, that are caused by a fundamental misunderstanding of how background execution works on iOS. These come in many different variants, for example: How do I keep my app running continuously in the background? If I schedule a timer, how do I get it to fire when the screen is locked? How do I run code in the background every 15 minutes? How do I set up a network server that runs in the background? How can my app provide an IPC service to another one of my apps while it’s in the background? How can I resume my app in the background if it’s been ‘force quit’ by the user? The short answer to all of these is You can’t. iOS puts strict limits on background execution. Its default behaviour is to suspend your app shortly after the user has moved it to the background; this suspension prevents the process from running any code. There’s no general-purpose mechanism for: Running code continuously in the background Running code at some specific time in the background Running code periodically at a guaranteed interval Resuming in the background in response to a network or IPC request However, iOS does provide a wide range of special-purpose mechanisms for accomplishing specific user goals. For example: If you’re building a music player, use the audio background mode to continue playing after the user has moved your app to the background. If you’re building a timer app, use a local notification to notify the user when your timer has expired. If you’re building a video player app, use AVFoundation’s download support. Keep in mind that the above is just a short list of examples. There are many other special-purpose background execution mechanisms, so you should search the documentation for something appropriate to your needs. IMPORTANT Each of these mechanisms fulfils a specific purpose. Do not attempt to use them for some other purpose. Before using a background API, read clause 2.5.4 of the App Review Guidelines. Additionally, iOS provides some general-purpose mechanisms for background execution: To resume your app in the background in response to an event on your server, use a background notification (aka a ‘silent’ push). For more information, see Pushing background updates to your App. To request a small amount of background execution time to refresh your UI, use BGAppRefreshTaskRequest. To request extended background execution time, typically delivered overnight when the user is asleep, use BGProcessingTaskRequest. To prevent your app from being suspended for a short period of time so that you can complete some user task, use a UIApplication background task. For more information on this, see UIApplication Background Task Notes. To download or upload a large HTTP resource, use an NSURLSession background session. All of these mechanisms prevent you from abusing them to run arbitrary code in the background. As an example, consider the NSURLSession resume rate limiter. For more information about these limitations, and background execution in general, I strongly recommend that you watch WWDC 2020 Session 10063 Background execution demystified. It’s an excellent resource. Specifically, this talk addresses a common misconception about the app refresh mechanism (BGAppRefreshTaskRequest and the older background fetch API). Folks assume that app refresh will provide regular background execution time. That’s not the case. The system applies a range of heuristics to decide which apps get app refresh time and when. This is a complex issue, one that I’m not going to try to summarise here, but the take-home message is that, if you expect that the app refresh mechanism will grant you background execution time, say, every 15 minutes, you’ll be disappointed. In fact, there are common scenarios where it won’t grant you any background execution time at all! Watch the talk for the details. When the user ‘force quits’ an app by swiping up in the multitasking UI, iOS interprets that to mean that the user doesn’t want the app running at all. So: If the app is running, iOS terminates it. iOS also sets a flag that prevents the app from being launched in the background. That flag gets cleared when the user next launches the app manually. This gesture is a clear statement of user intent; there’s no documented way for your app to override the user’s choice. Note In some circumstances iOS will not honour this flag. The exact cases where this happens are not documented and have changed over time. Finally, if you have questions about background execution that aren’t covered by the resources listed here, please open a new thread on DevForums with the details. Tag it appropriately for the technology you’re using; if nothing specific springs to mind, use Background Tasks. Also, make sure to include details about the specific problem you’re trying to solve because, when it comes to background execution, the devil really is in the details. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Change history: 2024-03-21 Added a discussion of ‘force quit’. 2023-05-11 Added a paragraph that explains a common misconception about the app refresh mechanism. Made other minor editorial changes. 2021-08-12 Added more entries to the common questions list, this time related to networking and IPC. Made minor editorial changes. 2021-07-26 Extended the statement about what’s not possible to include “running code periodically at a guaranteed interval”. 2021-07-22 First posted.
0
0
12k
Mar ’24
Check if Background URLSession with identifier exists
I have a working background URLSession. I know that upon creating an URLSession with the same session identifier I get a "background URLSession with identifier x already exists" message. I know that I can store the session and call .finishTasksAndInvalidate() on it if needed. My use case is that if the application terminates, and the user relaunches the application before the background task completes, I need to be able to check if a background URLSession with the same identifier exists, and if it does, restitute the application state with the same handlers (so that I can update a UIProgressView for example). I have two questions: How do I check that a background URLSession with a given identifier already exists? Does the AppDelegate completion handler still get called if the application was terminated and relaunched?
5
0
1.9k
Aug ’23
HKObserverQuery BackgroundDelivery not executed
Hi, before installing iOS 15 our app received HKObserverQuery calls in background, which worked like a charm - the calls have reliably woken up our app in background, enabling it to process new HK data. In iOS 15 the new entitlement com.apple.developer.healthkit.background-delivery was added, being mandatory if HKObserverQuery calls should be delivered in background. Indeed, we added the entitlement to the Entitlements file and the Provisioning Profile of the app. After doing so, registering with enableBackgroundDelivery(for:frequency:withCompletion:) worked again without an error. While testing we observed that the app is not called at all. To debug, we captured system logs of an iPhone with iOS 15 - you can find them attached. syslog It can be seen that HK background delivery tries to fire, but dasd decides to not proceed because of the ApplicationPolicy. After some research we found this might be related to background modes capabilities. Thus we added "Background fetch" and "Background processing". Anyhow, this did not change the behavior. Again, this background delivery perfectly worked on iOS 14 - we did not change anything except adding the new background delivery entitlement (and the background processing entitlements in a second try). Are we missing any (new?) entitlements? Any other news in iOS 15 making further changes necessary? Is HKObserverQuery working for others in background mode? Thanks in advance for considering and best regards, Nils Notes on the logs: App was suspended at all times iPhone was unlocked from the beginning on iPhone was locked at 13:16
20
1
6.5k
Jul ’23
Background Tasks and time running in background
Our application allows people to back up their content (Photos / Videos) into the cloud. To have our backup working more efficiently while the application is in background, we have implemented background tasks. We schedule refresh and processing task (BGProcessingTask). Processing task is used for uploading content. We are looking into improving the number of triggers for processing tasks. There are one or two triggers in 24 hours but not as frequently as we expected. We did an exercise to compare google photo v/s our application: the time google gets to execute in background is 6 times more than personal cloud. What are the possible reason for this difference.  See some sample code below. We were lucky to have an appointment for a tech talk with @George V. from Apple and he suggested to use BGProcessingTask and set a flag to defer those tasks to run at a time where the device was less used. We do work with BGProcessingTask and are using the flags request.requiresNetworkConnectivity and request.requiresExternalPower. Where it's not clear for me is: would setting requiresExternalPower to true prevent our app to run in background while the device is not plugged? Any guidance would be appreciated :) Maybe @George, if you're available. Thanks import UIKit import BackgroundTasks @main class AppDelegate: UIResponder, UIApplicationDelegate {     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {         registerBgTasks()         //registerBatteryBgTasks()         return true     }     func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {     }     func registerBgTasks() {         BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.photos-upload",                                            using: nil) { (task) in             self.handleProcessingTask(task: task as! BGProcessingTask)         }     }     func registerBatteryBgTasks() {         BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.photos-upload-power",                                            using: nil) { (task) in             self.handlePowerProcessingTask(task: task as! BGProcessingTask)         }     }     func handlePowerProcessingTask(task: BGProcessingTask) {         let startTime = Date()         let taskId = task.identifier         if let url = URL(string: "https://imaging.nikon.com/lineup/dslr/df/sample.htm") {             let session = URLSession.shared             let networkTask = session.dataTask(with: url) { data, _, _ in             }             networkTask.resume()         }         task.expirationHandler = {             let endTime = Date()             let diffComponents = Calendar.current.dateComponents([.second], from: startTime, to: endTime)             let taskEntry = TaskEntry(taskId: taskId, taskLaunchedTime: DateUtility.readableDate(date: startTime),                                       taskExpirationTime: DateUtility.readableDate(date: endTime),                                       taskTotalTime: "\(diffComponents.second ?? 0)")             let fileName = "\(Date().timeIntervalSince1970)power.plist"             APIPreferencesLoaderPower.write(preferences: TaskArray(tasks: [taskEntry]), fileName: fileName)             task.setTaskCompleted(success: true)         }     }     func handleProcessingTask(task: BGProcessingTask) {         let startTime = Date()         let taskId = task.identifier         if let url = URL(string: "https://imaging.nikon.com/lineup/dslr/df/sample.htm") {             let session = URLSession.shared             let networkTask = session.dataTask(with: url) { data, _, _ in             }             networkTask.resume()         }         task.expirationHandler = {             let endTime = Date()             let diffComponents = Calendar.current.dateComponents([.second], from: startTime, to: endTime)             let taskEntry = TaskEntry(taskId: taskId, taskLaunchedTime: DateUtility.readableDate(date: startTime),                                       taskExpirationTime: DateUtility.readableDate(date: endTime),                                       taskTotalTime: "\(diffComponents.second ?? 0)")             let fileName = "\(Date().timeIntervalSince1970)normal.plist"             APIPreferencesLoader.write(preferences: TaskArray(tasks: [taskEntry]), fileName: fileName)             task.setTaskCompleted(success: true)         }     } } other class: func scheduleBgTask() {         let request = BGProcessingTaskRequest(identifier: "com.synchronoss.cloud.photos-upload")         request.requiresNetworkConnectivity = true         request.requiresExternalPower = false         do {             try BGTaskScheduler.shared.submit(request)         } catch {             print("error")         }     }     func schedulePowerBgTask() {         let request = BGProcessingTaskRequest(identifier: "com.synchronoss.cloud.photos-upload-power")         request.requiresNetworkConnectivity = true         request.requiresExternalPower = true         do {             try BGTaskScheduler.shared.submit(request)         } catch {             print("error")         }     }
3
0
2.3k
Sep ’23
Session immediately invalidated when using BLE background mode
Hello everyone, I have encountered an error when trying to enable BLE background mode of the third-party NI example application. I have done that by replacing the configuration = try NINearbyAccessoryConfiguration(data: configData) with configuration = try NINearbyAccessoryConfiguration(accessoryData: configData, bluetoothPeerIdentifier: peerIdentifier) I have additionally expanded the List.plist with Required background modes: App communicates using CoreBluetooth Or rather, central-bluetooth When starting the session, iPhone 12+ Pro Max (iOS 16+) device immediately calls invalidateSession with the error invalidSession. configData is identical for both cases, and implementation on peripheral device has not been changed. Important thing to note here is that for the non-background mode, third-party accessory and iPhone device are able to range just fine. Do you have any recommendations or advice how we can try to solve this, or what might be an issue? Thank you in advance, Aleksa and OBLO Living development team.
1
0
1.4k
Jul ’23
Background URL session upload task behavior in watchOS?
I’m working on an independent watchOS app which is primarily designed to to collect and periodically send location updates to a server. The UI features a toggle that allows the user to turn this capability on or off at their discretion. The typical use case scenario would be for the user to turn the toggle on in the morning, put the app in the background and then go about their day. Given the limitations and restrictions regarding background execution on watchOS, in an ideal situation, I would be able to upload the stored location updates about every 15-20 minutes. With an active complication on the watch face, it’s my understanding that this should be possible. I’ve implemented background app refresh and indeed, I do see this reliably being triggered every 15-20 minutes or so. In my handle(_:) method, I process the WKApplicationRefreshBackgroundTask like this: func handle(_ backgroundTasks: Set&lt;WKRefreshBackgroundTask&gt;) { backgroundTasks.forEach { task in switch task { case let appRefreshBackgroundTask as WKApplicationRefreshBackgroundTask: // start background URL session to upload data; watchOS will perform the request in a separate process so that it will continue to run even if our app gets // terminated; when the system is done transferring data, it will call this method again and backgroundTasks will contain an instance of // WKURLSessionRefreshBackgroundTask which will be processed below startBackgroundURLSessionUploadTask() scheduleNextBackgroundAppRefresh() appRefreshBackgroundTask.setTaskCompletedWithSnapshot(false) case let urlSessionTask as WKURLSessionRefreshBackgroundTask: // add urlSessionTask to the pendingURLSessionRefreshBackgroundTasks array so we keep a reference to it; when the system completes the upload and // informs us via a URL session delegate method callback, then we will retrieve urlSessionTask from the pendingURLSessionRefreshBackgroundTasks array // and call .setTaskCompletedWithSnapshot(_:) on it pendingURLSessionRefreshBackgroundTasks.append(urlSessionTask) // create another background URL session using the background task’s sessionIdentifier and specify our extension as the session’s delegate; using the same // identifier to create a second URL session allows the system to connect the session to the upload that it performed for us in another process let configuration = URLSessionConfiguration.background(withIdentifier: urlSessionTask.sessionIdentifier) let _ = URLSession(configuration: configuration, delegate: self, delegateQueue: nil) default: task.setTaskCompletedWithSnapshot(false) } } } And here is how I'm creating and starting the background URL session upload task: func startBackgroundURLSessionUploadTask() { // 1. check to see that we have locations to report; otherwise, just return // 2. serialize the locations into a temporary file // 3. create the background upload task let configuration = URLSessionConfiguration.background(withIdentifier: Constants.backgroundUploadIdentifier) configuration.isDiscretionary = false configuration.sessionSendsLaunchEvents = true let backgroundUrlSession = URLSession(configuration: configuration, delegate: self, delegateQueue: nil) let request: URLRequest = createURLRequest() // this is a POST request let backgroundUrlSessionUploadTask = backgroundUrlSession.uploadTask(with: request, fromFile: tempFileUrl) backgroundUrlSessionUploadTask.countOfBytesClientExpectsToSend = Int64(serializedData.count) // on average, this is ~1.5 KB backgroundUrlSessionUploadTask.countOfBytesClientExpectsToReceive = Int64(50) // approximate size of server response backgroundUrlSessionUploadTask.resume() } Note that I'm not setting the .earliestBeginDate property on the backgroundUrlSessionUploadTask because I'd like the upload to start as soon as possible without any delay. Also, this same class (my WatchKit application delegate) conforms to URLSessionTaskDelegate and I have implemented urlSession(_:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:) and urlSession(_:task:didCompleteWithError:). In my testing (on an actual Apple Watch Ultra running watchOS 9.3.1), I've observed that when the system performs the background app refresh, I always receive a callback to myhandle(_:) method. But when I start the background URL session upload task (in startBackgroundURLSessionUploadTask()), I was expecting that when the upload completes, I'd receive another call to myhandle(_:) method with an instance of WKURLSessionRefreshBackgroundTask but this doesn't seem to happen consistently. Sometimes I do see it but other times, I don't and when I don't, the data doesn't seem to be getting uploaded. On a side note, most of the time, startBackgroundURLSessionUploadTask() gets called as a result of my code handling a background app refresh task. But when the user turns off the toggle in the UI and I stop the location updates, I need to report any stored locations at that time and so I call startBackgroundURLSessionUploadTask() to do that. In that specific case, the upload seems to work 100% of the time but I definitely don't see a callback to my handle(_:) method when this occurs. Am I wrong in expecting that I should always be getting a callback to handle(_:) when a background URL session upload task completes? If so, under what circumstances should this occur? Thanks very much!
1
0
857
Mar ’24
Called endBackgroundTask but not working
When my app enter to background, I start a background task, and when Expiration happens, I end my background task. The code likes below: backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ dispatch_async(dispatch_get_main_queue(), ^{ if (backgroundTask != UIBackgroundTaskInvalid) { [[UIApplication sharedApplication] endBackgroundTask:backgroundTask]; backgroundTask = UIBackgroundTaskInvalid; [self cancel]; } }); }]; When the breakpoint is triggered at the endBackgroundTask line, I also get the following log: [BackgroundTask] Background task still not ended after expiration handlers were called: <UIBackgroundTaskInfo: 0x282d7ab40>: taskID = 36, taskName = Called by MyApp, from MyMethod, creationTime = 892832 (elapsed = 26). This app will likely be terminated by the system. Call UIApplication.endBackgroundTask(:) to avoid this. The log don't appear every time, so why is that? Is there something wrong with my code?
2
0
1.6k
Aug ’23
WeatherKit in a background operation?
Sorry if this is a stupid question but I haven't been able to find any information on whether an app can request and receive weatherKit data - the weather - while in the background. My app (AirCompare) makes extensive use of background URL sessions to fetch and process weather data. If certain conditions are met, a notification alert is sent to the user so the user can decide whether to activate the app. For instance if rain is in the forecast, the app alerts the user that they might want to close their windows. Making the app active will execute HomeKit control and accomplish that. Will I be able to replace the background URL session with the appropriate code and be able to fetch weather data in the background?
2
0
842
Jul ’23
Does BGAppRefreshTask get called when your app is foreground or connected to the debugger?
I have yet to see iOS call my background task. I can get it to call it with the debug support (_simulateLaunchForTaskWithIdentifier), but not on its own. Does being foreground suppress the task call? Does being connected to the debugger (but in the background) suppress the call? Does an Xcode-installed app get its background task called? What is the Xcode scheme Run Info option “Launch due to a background fetch event"? Xcode 15b1 and iOS 17b1.
0
0
841
Jun ’23
Launching a mac app upon login AND keeping it running forever
I did some research and found that we can add our app by bundling a 'helper app' inside the main app's Contents/Library/LoginItems. Then in the main app (say from app delegate didlaunchwithoptions), call SMLoginItemSetEnabled and pass it the bundle identifier of the helper app and flag=true. This is way, when the main app is launched, it will configure the helper app as the 'login item', and that helper app will be launched automatically upon system login. Then in the helper app launch process, check if the 'main app' is not running, open it by using its path/url. But we also want that users are not able to quit (or force-quit) the main app (it's a security app). Or at least, if they kill the app, it should be relaunched automatically. Will just doing the above achieve all this? app should be launched upon system login app should be launched if it's killed by any way If not, what are the options?
1
0
585
Jun ’23