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.
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.
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.
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...
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 ...
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.