6

OK, so I specified a UIRequiresPersistentWiFi key of my App's plist to YES so the iOS won't stop fetching the data when my app is in the background.

However, when the user uses cellular connection (not wifi) and my app is in the background, the download of the data is stopped after several minutes.

I double checked the docs and it seems there is no equivalent of UIRequiresPersistentWiFi for cellular network that I could set.

Is there any way I can make the connections over cellular network survive while the app is in the background? Any hints?

Cheers!

Updates:

I am making an Internet radio app. Stream is combined with mp3s which I request one after another (can't request them in advance, can't change server side). It works when my app is in the background and uses wifi. However, when using cellular connection the network requests are not performed after some time spent in the background. There is no place for changing the strategy. The app is in the AppStore and it had worked before. I guess they changed something in the new version of the system.

What is more I do not need throttling. My radio app has been already approved and is in the AppStore. The stream is sent with 128kb/s (that is the maximum) so that is not a problem. It looks like system silences my network requests (when on cellular network) after some time in the background. However, this only happens when I try to start the connection in the background.

Description:

  1. App is in the background playing a mp3 streamed over cellular network.
  2. Mp3 ends
  3. I request the URL to another mp3
  4. The request is not performed*.

*works when using WiFi.

Rafał Sroka
  • 39,540
  • 23
  • 113
  • 143

3 Answers3

11

I'm fairly certain there isn't something like this for Cell networks. Here is my reasoning:

  • Cell service costs money. A LOT of money. Per minute. Wifi service does not cost money, in comparison.
  • AT&T does not have very much bandwidth, and charges users extra for extra bandwidth usage.
  • Apple is a company that wants to make the user experience as clean and nice as possible.
  • When costs are exorbitant through no fault of their own, users are angry and their experience is not nice.

If Apple lets you have a constant connection to the web outside of wifi range, the user's cost of service would skyrocket and they wouldn't know why. And if Apple gives programmers this ability, somebody would abuse it. So, I'm sure that Apple won't allow you to do that.

Why do you need a constant internet connection when your app is in the background anyway (unless, I guess, you're making an internet radio app)? Keep in mind that, when in the background, your app can be terminated without warning at any time. You may want to rethink your strategy if you can't find a way to do this. :/

Tustin2121
  • 2,058
  • 2
  • 25
  • 38
  • I am making an Internet radio app. Stream is combined with mp3s which I request one after another (can't request them in advance). It works when my app is in the background and uses wifi. However, when using cellular connection the network requests are not performed after some time spent in the background. There is no place for changing the strategy. The app is in the AppStore and it worked. I guess they changed something in the new version of the system. – Rafał Sroka Jan 20 '12 at 08:39
  • Had I known, I wouldn't have said to rethink the strategy. As for the requesting mp3 thing, I take it you've already tried to constantly stream the audio, without having to re-request the audio stream? I know Apple was getting flack for background apps draining battery when they first brought up multi-tasking. Chances are what changed was Apple's strategy for keeping background apps from taking up battery and bandwidth (It is, after all, a lot more battery intensive to do a cell connection than a wifi connection) – Tustin2121 Jan 23 '12 at 16:04
  • My approach had worked before. My conclusion is that Apple has become more strict and does not allow performing requests while the app has been in the background for some time and uses cellular network. I tried all workarounds that came to my mind. None of them fixed this issue. – Rafał Sroka Jan 24 '12 at 10:06
1

I think there is no equivalent of UIRequiresPersistentWiFi, there reasons probably include the ones pointed out by Tusting2121.

But please note that UIRequiresPersistentWiFi is connected with energy saving. The wifi module consumes energy, so normally it is shut down after some time to save some energy unless UIRequiresPersistentWiFi is set. Such enrgy saving, I believe, is not a case in cellular case.

And the fact that your connection disappears after certain minutes in cellular mode may be caused by something completely different that the copy of wifi energy saving mechanism you claim. See for example this article which suggests that you are obliged to throttle your 3G data flow.

Krizz
  • 11,362
  • 1
  • 30
  • 43
  • Thanks for the suggestion but I do not need throttling. My radio app has been already approved and is in the AppStore. The stream is sent with 128kb/s (that is the maximum) so that is not a problem. It looks like system silences my network requests (when on cellular network) after some time in the background. However, this only happens when I try to start the connection in the background. – Rafał Sroka Jan 20 '12 at 08:45
1

Add audio to your UIBackgroundModes entry in Info.plist.

According to the Apple Docs: In your callbacks, though, you should do only the work necessary to provide data for playback. For example, a streaming audio app would need to download the music stream data from its server and push the current audio samples out for playback. You should not perform any extraneous tasks that are unrelated to playback.

You may also get some value out of the voip entry - you can setKeepAliveTimeout:handler: to have your handler called on a periodic basis to populate your data stream.

ikuramedia
  • 6,038
  • 3
  • 28
  • 31
  • Thanks for the answer but I already have the audio key in UIBackgroundModes entry. I also think I should not add voip key. This may lead to the app rejection since my app does not use any VoIP services. – Rafał Sroka Jan 23 '12 at 08:37
  • 1
    Are you queuing up separate mp3 files and then playing them one-by-one? It could be that when you stop playing the last queued up file the app gets suspended? From the docs `However, if the application stops playing that audio or video, the system suspends it.` Do you stop playing and then start the next file? Is there a way to continually load your buffer instead of letting it drain? – ikuramedia Jan 23 '12 at 10:35
  • Otherwise, we'll need more details - does it stop playing after the same amount of time each time? Or the same number of songs? Is it between songs or in the middle of a song? How are you requesting your data from the network? What callbacks are you using to load the next tunes? Etc... – ikuramedia Jan 23 '12 at 10:36
  • I am not queuing them. After the first is finished I request the URL to another one and start playing it. That's not a infinite stream. I updated my question with some description. – Rafał Sroka Jan 23 '12 at 11:30
  • 1
    From your description, it seems like the problem is caused by Step 2. When you stop playing the mp3, the OS determines that you're done with background execution and suspends your app. You can probably confirm this with logging. In that case, you need some method to queue up the next track so that you can continue playing audio and avoid being suspended. Or you need to find a way to keep the audio channel open (playing a silent file?) while you perform the network request. – ikuramedia Jan 23 '12 at 14:32
  • It would be like you said if it happened in both cases - WiFi and Cellular. However, when I use WiFi, everything is ok and works well. So, it seems that it is not related with audio playback but with network connections using cellular network in the background. – Rafał Sroka Jan 24 '12 at 10:09