Is uploading allowed in background fetch (PerformFetch) - ios

I'm using C# (Xamarin) on iOS, but I suspect this question applies to those programming in Objective C as well. iOS 7 introduces the background "fetch" functionality which lets the app download data while it is in the background.
All of the docs I've read (on both Xamarin's and Apple's sites) state that this functionality is for downloading updates, and that you have around 30 seconds to finish the download; however, nowhere are restrictions stated. I'm wondering if it's acceptable for my app to also upload things to our servers when in the background.

Yes!
Sorry for the short answer. I have implemented fetch in one of my apps available in AppStore where I upload or download a very small txt file. You are right about 30 sec window. So far its been working fine with no problems.
You can even simulate fetch upload and download in your XCode simulator to see if you run into any time limit problem.
Again the point of fetch is to keep your upload / download data light and you already know that you cannot control how frequent fetch wakes up to do those action. It maybe every 10 mins or once a day depending upon users internet usage pattern.

Yes you can upload data/file whenever Background fetch method is triggered and you are right like rain about the 30 sec window.
I have managed to increase the 30 sec window to around 180 sec (3 mins) by combining the background fetch with UIBackgroundTaskIdentifier.
From iOS 7 180 sec (3 mins) is the maximum permitted time for iOS apps for background execution before the app goes into suspended mode, Earlier it was around 600 sec (10 mins).

Related

Background Fetch Enumerations

In iOS the outcome of a background fetch could be one of the following:
UIBackgroundFetchResultNewData
UIBackgroundFetchResultNoData
UIBackgroundFetchResultFailed
In what way does iOS care about the outcome?
I understand that a fetch that lasts too long (I believe 30 secs or more) is penalized by giving less fetch opportunities to the app.
Does any of the above, specifically NoData and Failed have repercussions as well?
Or is this just for internal processing?
Why not just return UIBackgroundFetchResultNewData every time?
The precise algorithm used by Apple is not described, but in the iOS Application Programming Guide Apple states,
Apps that download small amounts of content quickly, and accurately reflect when they had content available to download, are more likely to receive execution time in the future than apps that take a long time to download their content or that claim content was available but then do not download anything.
It seems that iOS observes your app's behaviour. If it claimed that new content was available (returned UIBackgroundFetchResultNewData) but it did not actually perform a network operation it may receive less frequent background fetch opportunities. It pays to be honest.
I also seem to remember reading somewhere (but can't find a reference now) that iOS can use the completion value to determine the times of day when your server may have new content (For example, if the fetch around 1am consistently returns new data and the fetch at 6pm consistently doesn't, iOS may be more likely to perform a background fetch for your app at 1am).
You should aim to complete the fetch as quickly as possible, but do not call the completion handler until the fetch is complete or your app will be suspended without completing the download. You can also use beginBackgroundTaskWithExpirationHandler to get more time, but your app has a limit of 180 seconds, total, of background execution per 'backgrounding' (ie. If the user brings your app back to the foreground and then suspends it again the 180 seconds is reset).

Before iOS7 was it possible to execute background task if it didnt involve audio, location etc

Apple has provided certain services which can run in the background for 10 minutes, but what if I have to perform some other task like downloading a file ... how much time limit do I get for it
Before iOS 7 you could request up to 10 minutes of background time (via beginBackgroundTaskWithExpirationHandler:) or you could use any of the background modes available at the time (such as location, voip, etc).
VoIP handler, for instance, will be called at most every 10 minutes and will give up to 3 minutes of background time IIRC.
With iOS 7 you can download and upload files out-of-process, without your app running. Please check documentation on NSURLSession and NSURLSessionConfiguration.
You can do it (directly after your app went to the background, that is, not let's say an hour later), and you approx. do have 10 minutes, although that is not guaranteed. See here in the apple documentation:
https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW20
You can request a Executing a Finite-Length Task in the Background
which will run in background for maximum 10 min. This should be long enough to download file.
So no it is not just for certain services, you can get your app running the background for a longer period of time if your app is a VOIP app, track user location, playing audio or your app is app for an external accessories.

Background Upload too slow using NSURLSession in iOS

I am trying to upload a huge video file using NSURLSession background upload task. I break the file into chunks of 256Kb and upload them. When the app is in foreground the upload of chunks happen real quick (5 seconds for 256Kb). But when the app is pushed to background though the upload continue to happen the speed of it is reduced crazily (5 minutes for 256Kb). Any thing wrong here or any thing I need to take care of ?
When your app is in the background, the user has indicated that whatever it's doing is not as important as something else. The system will throttle the background network tasks because they are not as important.
There is also the discretionary property on the configuration object which will, among other things, prefer to download when connected to power and wi-fi. If the download is initiated while the app is in the background, the download will behave as if the discretionary flag were true.

Does NSUrlSession Prevent the Application from suspending?

I have an app that send 300+ files across the network, normally we request an additional 10 minutes timer when the app moves to the background in case we need to send, but after 10 minutes the app is moved to the suspended state.
Can NSUrlConnection prevent this suspension and continue download from the background>
you get only 3 minutes in iOS 7, not 10 as before.
NSURLConnection cannot help you there.
NSURLSession has a facility for uploading files in the background, outside of that time. However, it doesn't keep a continuous task running like UIBackgroundTaskIdentifier-based methods, and you must use on-device files as the basis of the upload. I found it to take a lot of work to get it right, so be prepared. I'd start with a thorough review of Apple's URL Loading System Programming Guide, which isn't really well written, but is entirely necessary.

IOS background application can use library to download resources periodic?

I am working a cocoa touch static library for the applications, and the library has a feature to download network resources by NSOperation in the period time, and provide some methods.
I knew the IOS applications enter the background has limited,(like 5 seconds in main thread, 10 min to long task...) So I want to know IF some application used my library entered in the background, My Library's period download task will be terminated or alive? And the application also used my library's function successfully?
Think of moving into the background as having your app 'freeze dried" - all state is frozen at that moment. When your app moves to the foreground, then the app starts running using the now somewhat dated information. NSTimers etc will continue to work but the "gap" between the last firing and the next firing will be huge. [I believe (but don't recall for sure) that if you had had a timer set for 2 min, and you went into the background with 1 min remaining for say 10 min, that when you move to the foreground the timer will fire immediately].
What I ended up doing was keeping a NSDate object that had the time of the last firing - so I could detect large gaps due to getting moved into the background - and taking appropriate action.
Note that web fetches etc that were in process should just return a timed out status - but again, if you keep a NSDate around of the time you initiated the fetch, you can detect this case.

Resources