In my application I want to run periodic task. For this I'm using setInterval It's important to notice that the app doesn't have to be in foreground state for the task to run.
On iOS, I use significant location changes to wake-up the application, check some conditions and then start the periodic task this works fine.
On Android, I'm facing some problems with the setInterval. I'm using foreground service,
and when some conditions are met, I want to execute the periodic task, however it never starts. What I've noticed is that if and only if the app is in the foreground state the setInterval actually works. Even if I press the home button and put the app paused state, setInterval stops working.
What I understand from here, is that on Android setInterval requires the UI thread to run but on iOS it doesn't. Is my conclusion is true? Are there any under the hood differences between the setInterval implementations on iOS and Android.
I am developing one app using react-native and expo in which I have one stopwatch where I am using setInterval to update stopwatch timer its working fine in foreground but when I minimize the app the timer stop working.
After reading lot of documents I found that using expo-task-manager we can run things in background but I don't know how to use it with setInterval.
Thank you in advance
Unfortunately setInterval can not run when app is in back ground, you can do it with AppState listeners, so when your app goes in background and come in foreground calculate the time difference and use setState/useState methods.. to maintain a state..
I am trying to get the correct event for the first start up in a react native app.
I understand AppState and can get these statuses from the React Native Docs
App States
active - The app is running in the foreground
background - The app is running in the background. The user is either
in another app or on the home screen
inactive - This is a state that occurs when transitioning between
foreground & background, and during periods of inactivity such as
entering the Multitasking view or in the event of an incoming call
In the docs it mentions that when the app first loads AppState.currentState will be null, but I can find when that would happen.
Why do I even care you ask, I am trying to send a "login" event, but I don't want it every time the app becomes active. If it is relevant I am working on a cross platform app, both Android and IOS need to be supported.
In my app, I have performed the following listed below and have added counter to the app fetch routine to highlight the number of times fetch is called by iOS 8.1.
Turned on Background Modes and enabled background fetch.
Wrote code for “performFetchWithCompletionHandler”. NSLog message indicate the start and end of the fetch process. Counters are between these messages.
Added code in “didFinishLaunchingWithOptions”. However, instead of using “setMinimumBackgroundFetchInterval” I am using double of 60 assuming seconds.
When I test the code in Debug by setting “Simulate Background Fetch” all works perfectly as expected with absolutely no problems. Counters work and show expected values.
However, when I go live on the iPhone, launch the app, then hit the home button to put in background, wait one or two hours or overnight. Nothing happens, no fetch, no downloads and all counters remain at zero.
If I cannot get this to work, I will need to create my own background thread and manage it directly, which I would prefer not to do.
Any input or ideas are deeply appreciated.
As of iOS 8, I started having this same problem with both of my apps. In iOS 7, background refresh triggered pretty reliably. In iOS 8, it just stopped. If I launch either app from xcode into the background fetch mode, everything works like it should. Background refreshes themselves just stopped triggering on their own in iOS. I have a hopeful theory that I'm trying out right now. Here's my thinking...
iOS will exclude your app from background refresh if the user force kills it from the multi-tasking screen. How might Apple have implemented this behavior? One way would be to just set your minimum fetch interval to UIApplicationBackgroundFetchIntervalNever. Easy peasy. Let's assume that's how they do it. Does your app set the minimum fetch interval every time it launches, or does it only set it on the initial launch?
In my case, I was only setting the minimum fetch interval as part of the initial setup of my app. If the user force killed the app, and iOS is in fact setting the minimum fetch interval to UIApplicationBackgroundFetchIntervalNever, then my apps are stuck in the state of never. I made a minor change in one of my apps, so that it sets the minimum fetch interval on every launch. So far so good.
Update:
All is well in my background fetch land.
Both my app that's currently in development and my app that's in the app store are once again triggering background fetches reliably.
The code for doing this can be pretty simple...
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:minimumBackgroundFetchInterval];
Calling that every time your application launches will do the trick, however, you'll want to consider whether setting that value is appropriate to the current state of your app. In my case, one of my apps is a concert listings app. There's no point in setting a minimum background fetch interval if the user hasn't selected a location for concerts yet. I have an NSUserDefault to track whether a location has been set. Here's an approximation of my code for setting the fetch interval ...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([INCUserDefaults isLocationConfigured]) {
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:kSecondsIntervalForUpcomingShowsBackgroundFetch];
}
return YES;
}
Prior to the bug fix that I issued, I was only setting the minimum background fetch interval as part of the setup process. Now I set it during the setup process, and on application startup if the setup process was previously completed.
Apple uses a secret algorithm to determine the frequency of fetch events. This algorithm is presumably based upon app usage patterns (ie: how frequently and when the user users the app). It can take several days before fetch events begin to arrive consistently.
If fetch event works in simulator, that proves that everything is correctly set up. There's nothing you can do but wait.
iOS does the background fetch in certain way. It wakes up apps it believes the user uses often. Try opening the app after you wake the phone for a few times.
As kkarayannis wrote, iOS will learn how often to call your app. I've seen the same behaviour as I wrote my first background fetch. I believe, that you should not only open your app manually, but also trigger a manual refresh then. IOS will learn that the user wants to load data regularly and will start to do it on it's own.
Have you also tried to use "setMinimumBackgroundFetchInterval" instead of 120sec? Maybe it's a too short intervall. However you could also past your code for better understanding.
I'm building a Windows Store app and it pops up toast notifications from time to time. I also have an animation that plays to show when something has updated. Both of these happen at the same time.
What I would like is to not show the toast when the app is running.
So, is there a nice easy way to determine this or do I have to manually track the state via the suspending/resuming events?
Edited info:
The solution has a background task project which goes off, gets the data, then decides if anything has changed that the user needs to know about.
If so, it creates a toast, updates the tile badge, and plays an animation to fade in the new data.
The issue is that I don't want to show the toast and update the tile badge if the user has the app full screen. Similarly, playing the animation isn't needed until the app is resumed (that's the easy part though).
I realize I could solve it by having one timer that works when the app is running, and a separate background task for when it's suspended but that seems like overkill in this case.
The simple answer here is that if your app is suspended, your code won't be running.
If you want to pop up toasts when your app is suspended, you'll either need to use the WPNS or a background task to track changes.