This question already has answers here:
iOS do scheduled operation in background or when app active
(3 answers)
Run a task at fixed time everyday
(1 answer)
Closed 2 years ago.
I am creating an app that should check something in regular intervals. (Not a service call just harmless check which won't take much of CPU usage)
To run a code in background for a fixed interval of time, I tried using BackgroundTasks framework. My idea was to schedule one background AppRefresh task and schedule another when the first one gets called. Also in the whole day I tried with this framework, there were no updates. Though I always scheduled to run my job after 5 minutes, I sometimes waited for an hour for updates.
The code is working, I used the console command to simulate the background task and it worked.
I am not sure what framework I should use to achieve this?
Related
I have CoreData model which I want to update at 12 AM. So it's kind of an even when the app can recognize that a new day is coming and at 12 AM change some things in data models.
Initially, the idea was:
Prepare a single function that returns updated data. So before the function returns smth I every time check for the time (NSDate interval between two dates) and then update data model (if it's a new day). But the architecture not so simple for this purpose and it will take some time to prepare for a single point where I can get updated data, also it takes some time in background to update CoreData model which also adds some expenses to this task.
Is this ok solution to use some timer which will update data at 12 AM, I don't care about consistency in this case, but I don't like a timer which is checking every single second is 12 AM already or not. Is there some push notification update or some scheduler manager in iOS which can update data for me. One more time I just want to update the data layer and I don't care about consistency in UI. If consistency matter for sure then I would like to follow initial ide with a single point of retrieving data.
So I probably need some scheduler manager for this purpose or rewrite code of how I get the data.
There is no way to execute a function at regular intervals, even when the app is backgrounded/killed by the user.
The most reliable solution for executing a function at regular intervals even when the app is backgrounded is to use push notifications scheduled for the specific time intervals (midnight each day in your case), which would wake up the app and let it update its data. However, this solution has its downsides, since you need a server to send the push notification from and the users device needs to be connected to the internet. Also, push notifications don't wake up the app in case the user manually killed it.
For your particular problem, the best solution would be to refactor your code in a way that you have a single function that can be used to retrieve data and hence this function could ensure the data is updated in case a certain time interval has passed since the last update.
You might want to look into BGProcessingTask. You won't have granular control over when you're granted CPU time but you can set the interval you'd prefer that the task execute. Ultimately, when you run and how often is up to the system.
I would recommend checking out the new BackgroundTasks Framework Apple releases for iOS 13.
https://developer.apple.com/documentation/backgroundtasks
While you are not guaranteed at specific time if you have a window (12 am - 3 am) scheduling background tasks may be sufficient for you.
This question already has an answer here:
How to have Firebase automatically delete values older than 30 minutes
(1 answer)
Closed 4 years ago.
Is there any simple and free way to delete data older than 30 minutes?
even if the user's app is terminated
so its completely independent from the device's timing
thank you
You will need to write a cron job using App engine which triggers a function to delete previous data.
See this for example :
https://cloud.google.com/appengine/docs/standard/nodejs/quickstart
This is a simple example project here : https://github.com/GoogleCloudPlatform/nodejs-docs-samples/tree/master/appengine/hello-world/standard
if you clone this you will find an app.js file , you will have to write the function which will delete the data according to your logic.
I have read this answer and I do not believe it has what I am looking for but I a am beginner and I am happy to have someone point out the answer in this link : dispatch_after - GCD in swift?
My goal: set a function to run at 9 AM in the user's time zone (or system's time zone) every single day.
I've used GCD very briefly to delay a function as follows (it works perfectly fine):
var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(10 * Double(NSEC_PER_SEC)))
dispatch_after(dispatchTime, dispatch_get_main_queue(), {
let alert = UIAlertView()
alert.title = "Foo Alert"
alert.message = "foo."
alert.addButtonWithTitle("OK")
alert.show()
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
});
So I wanted to fire it daily as I've mentioned above but the first thing I am stuck on is swapping out DISPATCH_TIME_NOW for a time zone relevant value? Do I even need to consider time zones or will simply replacing DISPATCH_TIME_NOW with military 09:00 be sufficient?
Also, any advice on the overall goal, scheduling to fire function same time every day would be much appreciated.
I'm also not married to using GCD for this goal but it was the one I ran into the most doing searches.
In short, you cannot generally execute some arbitrary function at some arbitrary time unless the app is still running. The dispatch_after presumes that the app is still running at the scheduled time, which is not generally assured. The dispatch_after is great for "do something in x seconds", not "do something tomorrow at 9am".
Yes, dispatch_after can perform some task on some background thread, but that's very different concept from having the app run in the background (i.e., when the app, itself, is no longer in foreground). Please refer to App Programming Guide for iOS: Background Execution, which enumerates all of the various background mechanisms.
The key technologies for performing something when the app is not currently active include:
Using background fetch, you can opportunistically check for new data on the server (but not per your schedule, but rather at the discretion of the OS).
If your app is serving several very specific tasks (e.g. music app, VOIP, navigation app, etc.) you can register for background operation.
You can schedule a local notification to fire at particular time (though it is incumbent on the user to see the notification and tap on it in order for the app to run). For more information see the Local and Remote Notification Programming Guide.
You can register for push notifications and then your server could push a notification to clients at some time of your choosing (but that requires server-side development).
There are other background tasks that can be configured (e.g. continue network requests in background, request a few minutes to finish some finite length task even if the app is no longer active, etc.), but those seem unrelated to your question.
If you could clarify what you want the app to do at the scheduled time, we might be able to advise what is possible and what the alternatives are. But, in broad brush strokes, those are the basic options you have.
Importantly, you should use dispatch_walltime instead of dispatch_time. The difference: If you set a dispatch_time for "1000 seconds from now" it will run 1000 seconds from now (if your app is running). But dispatch_walltime will calculate which time that is on the user's clock, and will run when the user's clock reaches that time.
So if you set up dispatch_time for 9am tomorrow morning, and I set the clock on my device forwards by five minutes, then dispatch_time will run when my clock displays 9:05am. dispatch_walltime will run at 9:00am. (You'll have to experiment what happens if I change the clock from 8:55am to 9:05am because then running when the clock shows 9:00am is obviously impossible).
The iOS app that I am writing automation for, waits for 5 minutes before doing an activity and there are lot of cases I need to test when the 5 minutes are over. Is it possible to advance the app state to say 4 minutes and 15 seconds and then have every Appium test start from this point onwards so that overall my test suite runs faster - akin to having a save and restore state kind of facility? The default fullReset option is for a different purpose. Is there a way out?
thanks,
Paddy
Maybe You setting capability noReset to true will help?
It sounds like you want to create a snapshot of the app state. From my understanding, this is not possible - so you're going to have to wait the full duration every time.
From my experience in most cases you don't wait X amount of time rather than wait for activity to happen - Sometime the way to approach it is to wait constant time assuming that by then the operation will end. I usually try to understand how i can validate that the action ended - E.g. check the back-end or DB status - Than you can build a function that wait until the status is ready for the next step.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
iOS: Get location update every n minutes
How can I get location updates in the Background every 5 Minutes?
You should read the section Implementing Long-Running Background Tasks of in here.
And then pursue either register for significant location changes or declare itself as needing continuous background location updates.
Furthermore a solution to this problem was given here by wjans.
And I quote:
Found a solution to implement this with the help of the Apple
Developer Forums. I did the following:
•Specify location background
mode
•Use an NSTimer in the background by using
UIApplication:beginBackgroundTaskWithExpirationHandler:
•In case n is
smaller than UIApplication:backgroundTimeRemaining it does works just
fine, in case n is larger, the location manager should be enabled (and
disabled) again before there is no time remaining to avoid the
background task being killed. This does work since location is one of
the three allowed types of background execution.
Good luck :)