Consistent background fetch in iOS7? - ios

I was just wondering if it was possible to consistently update the data for my app every 60 seconds.
I have the following code right now:
NSTimeInterval testTime = 60.0;
[application setMinimumBackgroundFetchInterval:testTime];
However when testing on the simulator, the app initially grabs the data upon install, and then doesn't do anything else. My web searches tell me that iOS determines when to actually trigger background fetch.
That being said, is there anyway to consistently have background fetches occur for the user? Like say, for every 1 minute? My app's big selling point depends on the latest up to date information. I think it's possible, as apps like Gmail,twitter, SnapChat are always checking for new data...
Thanks

There is no way to achieve this using background fetch. You can only force this behavior using push (silent or otherwise), sending a push message to each device once every period of time.
Allow me to say, this is a terrible design. Polling is a terrible design for mobile apps. You should implement proper push notifications, notifying the user of new content, and loading it in the background as the OS deems possible.

Related

Periodic background synchronization

Im quite new to iOS programming and now want to implement a periodic background synchronization to synchronize my server data with client data. What I want to achieve is comparable with Androids SyncAdapter where you can define a time interval (for example each 30 minutes) and the system will trigger the defined task automatically in the background.
Until now I could not find such mechanism for Swift 3.0 so I need to ask if somone has experience or some hints for me how I can achieve this.
What I want to do sounds quite simple:
When the app starts for the first time the app should setup a sync manager which automatically triggers a background task every 30 minutes. The background task is responsible to synchronize server and client data (using Alamofire).
How can I do that?
There is an iOS feature called BackgroundFetch, which you can set up for
regularly downloads and processes small amounts of content from the network
You can setup a minimumBackgroundFetchInterval.
In contrast to the mentioned Android feature, this interval is not guaranteed though.
The OS does some heuristic in a blackbox. It rewards you for using a "reasonable" (to the OS) CPU time/ power consumption and also for being used often by the user. On the other hand you get punished for draining the battery or (even worse) never being used/opened by the user.
See: Apple Sample and Apple Docs
Update: Since iOS13, BackgroundFetchis deprecated.
There is a similar, new API named BGTask, BGAppRefreshTask is the equivalent to deprecated BackgroundFetch.
See Apple Docs
Alternatively, depending on your needs, you can post a Silent (push) Notification whenever the users data changes on server side. A silent push wakes up your app without notifying the user, so you can fetch data and maybe inform the user by scheduling a local notification.
See: Apple Documentation
You can't. Apple doesn't allow 3rd party apps to have regular background time like that. You'll need to come up with another approach like implementing a silent push notification from your server when new content is available.
As #ekscrypto points out in their comment, you can use Background fetch to load small amounts of data when the system decides to fetch it. However, you don't have any control over when that fetching takes place. Search on "Fetching Small Amounts of Content Opportunistically" in the Xcode help system for more information.

In iOS, is it possible to start region based geofencing at a particular time?

My iOS app (which targets iOS 8.1+) use location services to determine if a user has entered a particular region during an event. Ideally I would like to enable the geofencing a little before the event and turn it off a little after the event completes. The problem is there is no guarantee the app is running an hour before the event so I turn on geofencing at the point the user registers for the event. This is not the best approach as it means the geofencing is on for much longer than it needs to be.
As far as I can tell, there is no way to "wake up" the app in the background at a scheduled time in iOS. I could use the push notification meant for updating content, but It's not clear to me if Apple would reject such a misuse of that notification.
Any suggestions?
I've been looking into this myself.
If you can arrange a push notification from your backend ("Silent push notification", aka "content-available"), it seems to be a good option. In real-world situations, this seems to give you the best control over the timing. Unfortunately, it won't work if the person doesn't have connectivity. Also, unfortunately, you need a backend that can queue events at a time (not just in response to an input.) If you have such a backend already, and your app is only useful to the user when they have network coverage anyway, this is probably the best option. It seems this an appropriate use of the technology, so Apple should approve.
Another option I'm trying is to use background fetch. You specify a "minimum interval" to avoid too much fetching. Try 50% of the remaining time-to-event as a minimum. Every time the app wakes up (whether in the foreground because the user opened it, or in the background because background-fetch opens it) you can calculate the time-to-next-event, update the fetch interval, or start the region monitoring. You are supposed to use "background fetch" to fetch information from a server, but there doesn't seem to be any requirement to poll a server, you could poll your internal data instead. I haven't fully tested this yet but it seems promising.
You can use significant location change monitoring, which I've read will wake up your app briefly every 15 minutes or less, and you can use the time/location information to decide whether to turn on the geofence. I think this would work well in combination with the above "background fetch": Many hours or days before the event you rely on background fetch, which you then use to turn on significant location change monitoring a few hours before the event. (There's speculation that geofencing is actually more battery efficient than significant change monitoring, but you could choose to assume that other apps on the user's device will already by watching for significant changes, in which case the marginal cost of your app adding itself to the list should be minimal.)
Putting them all together, you could create a sequence of
background fetch -> significant location monitoring -> geofencing
as the time gets closer.
There is also the CLVisit monitoring functionality, it's not understood very well, but supposedly uses less power and is called less frequently than significant location change monitoring. If the background fetch or silent remote notifications aren't working to wake up your app, give this a try, and please report back!
You can't (yet) do a silent content-available local notification (AFAICT). However, perhaps you can schedule up a local notification "Your event starts tomorrow" or something that convinces the user to click the option that starts the geofence. Here's a tutorial on it http://www.appcoda.com/local-notifications-ios8/, the response of action can be UIUserNotificationActivationMode.Background so your geofence can come on (if the user responds to the notification) without bringing the app to the foreground.
It's been 5 to 6 weeks since you asked, do you have your own answer already? Please let me know.

Background fetch alternatives

I want to my app do some computations and then communicate with external server via HTTP. I would like to perform this operations both in foreground and background. It seems that Background fetch mode is best choice for me but I have some concerns related with this. What is the minimal time interval between fetches? I read somewhere this is 10 min, is that true? I read also that when user force quit fetches are no longer invoked. Is there any walk around to this? Finally, is there any alternative to background fetch? I saw there is Newsstand mode what looks promising. Can I use it for my purposes?
If you use background fetch or another background mode and don't really use it for the intended use, iOS will detect that an kill your app. (the most promising mode for that would be VOIP, but this would't make it into the App Store, as it's a cheat either)
You can start a background task, when your app enters background, what gives you 3 minutes time (iOS 7 and above).
As I did it before, you can schedule a local notification and use it to remind the user, that he should bring the app back into the foreground for more calculations, if he likes.

swift/ios refreshing app data when in background

I'm writing a iOS/Swift application which reads data from a REST service each X minutes and updates the UI accordingly.
Now I would like that when the app is put in the background, a task keeps being invoked at X minutes intervals reading from the REST service and, in case the data just read satisfies a given condition, show a notification prompting the user to bring the app back to the foreground.
In my searches I've read that during applicationDidEnterBackground event, I should start a task with beginBackgroundTaskWithExpirationHandler.
The problem is that, if I've understood correctly, this allows a maximum of 10/15 minutes after which the app is terminated if the task is not stopped with endBackgroundUpdateTask, while I want the task to keep polling the service indefinitely (at least until the user disable it from the app's settings)
My question is:
How is this kind of functionality performed normally? Do some common solutions or best practices exist for the solution of such a problem?
Use iOS Background Fetch feature where you can specify minimum background fetch interval. But actual interval between successive invocation of your code will be determined by iOS framework. For details checkout this link: http://code.tutsplus.com/tutorials/ios-7-sdk-working-with-background-fetch--mobile-20520
I use this approach in my app and I think it is a preferred way of doing.
You can use a local notification that can be presented from the background in case your condition is met.
Correct, iOS will eventually shut down the background process, you can't enforce continuous background activity. Use the backgroundTimeRemaining property to check how much time your application has left and try to handle it as gracefully as possible by calling endBackgroundTask so that iOS does not force kill your app.
As a solution, you could think about using remote notifications with with content-available : YES, which runs the didReceiveRemoteNotification
Have a look at the Parse.com Their local datastore is an abstraction for what you are trying to acheive.
By the way, is it really necessary to refresh in the background. If call is relatively quick, there is no need to refresh until the user open's the app. Background processes like that, using the net can be quite battery consuming when the user are not on a Wifi. So consider the use case carefully!

Can a background app (with a location UIBackgroundMode) use a timer to poll a server every few hours?

I have a background app with a UIBackgroundMode of location.
I would like my app to additionally contact a server every few or several hours to see if there is some new data for it (because using apple notification push would notify the user and that is not desirable).
Polling is something I would never use on any other OS, but with iOS they don't leave you much choice if there is certain functionality you would like to try to achieve.
If the polling interval is quite lengthy such as a few or several hours between polls, and the polling activity itself only lasts several seconds then the usual knee-jerk reaction about it draining battery life is greatly diminished.
Would a repeating NSTimer fire when an app is in background mode? If not is there another type of timer or mechanism available?
If it's just to check for new content, and not really time sensitive, you COULD use the significantChanges background location method...but if the user stayed fairly immobile it'd rarely/never fire. I would probably also add the update check in applicationWillEnterForeground to be more sure
No, that's not allowed. You should have a look at Push Notifications and find a server side solution.

Resources