I'm having trouble keeping wifi from disconnecting after 30 mins in an iphone app that needs to function when locked by the user.
The app normally does not sleep, but if the user so chooses they may lock the display. I'm adding a new feature to the app that sends data out over the network at 1 second intervals. prior to this there has been no network requirement for the app, and it has functioned as desired (music, timer-based processes) while user-locked.
The answer seemed to be here:
Wifi connection doesn't stay alive when asleep, with iOS4
But adding UIRequiresPersistentWifi boolean to info.plist doesn't keep it from timing out the wifi (i'm testing on Touch, iOS4.02) after 30 mins, even while the app is busy sending data out over the connetion. Maybe this only applies if the display sleeps itself, rather than user locks?
Related, I think there is no way to "stir" the display at any interval? User pressing the home button is sufficient to bring back the wifi; unlocking is not necessary.
Also, I've read on the interwebs that it was stated in a WWDC that UIRequiresPersistentWifi applies to keeping alive 3G as well. Can anyone verify?
thanks
Your app may be getting suspended by the OS after a long enough period of user inactivity.
Under iOS 4.x there are certain types of apps that aren't suspended when the display is locked (music player, VOIP, etc.) Apps that register as a VOIP type app might be allowed to keep a persistant network connection over a longer period. However Apple may require that an app actually provide some VOIP functionality in order to register for that type in any app submitted for review.
Is there some activity that you need to perform network activity? From iOS5 onwards, we have noted that even if we send network packets (heartbeat timers), then also iOS 5 blocks it after locking device.
It is to be noted that services which requires VoIP continue to receive calls, and notifications do come when your phone is on sleep mode or locked. This means that WiFi is not totally closed. I dont know how this happens.
As an alternative you can use data carrier of your network provider as an alternative to WiFi in case WiFi has gone down. With UIRequiresPersistentWiFi, you just inform iOS5 that you would require WiFi to run your application, nothing else signifies whether it keeps your screen ON or OFF. For keeping your phone from autolock you can however use disableTimer = YES flag, in lieu of your battery charge.
Related
I have specific requirement where i want to fetch data from the connected Ble Device every 15 mins for a period of time like form 10:00 PM to 10:00 AM. Can it be done when my app is in background and device is locked. Obviously, user won't keep the app in foreground for so long. Any suggestions on how to achieve this.
It may be achieved but unfortunately you need to solve this from device perspective.
Your device will need to wake up and initiate connection with your phone whenever you need to sync data. It will wake up your application and even launch it if it was terminated. You can then initiate a standard background process for which you have limited time to do whatever needs to be done. When complete you should disconnect from your device and wait for the process to be repeated.
There might be some hacks like using silent push notifications to wake up your app and try to connect but Apple will most likely not allow this plus there is a great chance your BT will simply not work in that state. Still it is something to try if you really need it.
You have the problem that you can't have a timer in an iOS app. Therefore you have some options that require specific behaviour of the peripheral.
One option is to let the app first connect, and always upon disconnect, it tries to reconnect. Then simply make the peripheral don't advertise for 15 minutes. As soon as it advertises again your app will be woken up because it connected. You can then fetch your data.
Another option is to be constantly connected and have a timer in the peripheral that notifies data every 15 minutes.
Both options requires you to have background capabilities enabled in your app and State Preservation and Restoration.
In background mode(app was killed) iOS device cant communicate with BLE.
Only scan BLE device which have service uuid.
Only background scanning is possible in iOS.
So u can get notification while peripheral was found in Background mode.
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:
App is in the background playing a mp3 streamed over cellular
network.
Mp3 ends
I request the URL to another mp3
The request is not performed*.
*works when using WiFi.
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. :/
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.
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.
I have a location based application that needs to run in the background. I have several iPhones that I am testing on including a older 3G. I register my app to need background location based services and everything works as advertised accept with the older 3G phone. When you press the lock button, it does an applicationWillResignActive: as expected, unfortunately the phone immediately goes into low power mode and that is that. When you have the phone tethered with the USB cable, and then press the lock button, the 3G phone stays alive and correctly reports location changes. When it is disconnected, it goes immediately into low power mode.
The strange thing is that I am pretty sure that it used to work. I want to see if anyone out there has an app running on an older iphone (3G) which registers for location services and is not immediately put into lower power mode when the lock button is pressed. If so, what am I doing wrong.
I followed all the directions, have locations in my Info.plist.
Thanks for your help!
Cheers,
Bryan
I think you are seeing expected behavior.
I noticed on a recent trip with my old 3g the Location Manager appeared to remain active only when the usb supplied power. On usb, unlocking the phone would bring the app up (google maps in this case) immediately with Location Manager active. Without usb, I had to relaunch Location Manager each time I unlocked the phone.
I strongly suspect this is safety/power-saving feature. The Location Manager sucks battery life at a startling rate, especially on older devices. By running the Location Manager continuously while on battery, you could easily flatline a user's phone without their knowledge.
I would be very leery of any design that requires the Location Manager to run continuously in the background. Test it throughly.
You don't want the economic consequences of users deciding that "when I use Bryan's app, my battery mysteriously dies" or the moral consequences of leaving someone in an emergency without a working phone.
I am developing a voice recording application that communicates with the server real-time, therefore requiring persistent Internet connectivity. I have included UIRequiresPersistentWiFi in my info.plist and have also disabled device going to sleep when the app is active. However, this understandably has a serious effect on the battery life of the device. Users end up having to leave this continuously plugged in. For an app that is touted as meant to replace handheld recorders, this is a serious shortcoming. My app also has many xml threads sent from iPhone to server, so wireless connectivity is of paramount importance.
My questions are:
1. Is it possible to somehow switch on UIRequiresPersistentWifi status only when required during a session. For example, can this be switched on only during transfers or xml updates to server and be switched off at other times?
2. Likewise, can IdleTimer be enabled and disabled programmatically at will during a session. For example, enabling idletimer only when no foreground or background tasks are running on the device.
Any other suggestion to ensure normal battery life? All my users will be on iTouch 4 or iPhone 4.
Any help/suggestions would be greatly appreciated.
Answer to part 2: Yes, you can enable and disable the idle timer depending on what the user or app is doing, and how long it's been. I know of a couple apps that disable the idle timer, but then re-enable it if the user doesn't touch any UI elements for 10 minutes, but then re-disables it if the user starts some long operation again. etc.
Partial answer to part 1: Using the radios (sending wifi data) takes power. A good way to save power is to not send data for as long as possible. Maybe buffer large amounts of data on the device, and try to burst upload it later.
My suggestion would be to not communicate with the server continuously, sorry :(
Is it possible to cache chunks of data into a file on the phone and transmit the chunks to the server periodically in one big burst? Same for the XML. Or does your app really really require it to be broadcast real-time?
And as far as I know, if you have specified UIRequiresPersistentWifi, you're stuck with it :(
Sorry, probably not the answer you want!
I am trying to determine feasibility of certain features required in a (potential) project. I am not (yet) looking for a how-to, just a can-do. I apologize for any vagueness and ignorance: the former due to an NDA that makes Apple's NDA look like GPL, and the latter due to the fact that I have no iPhone or MAC experience.
I do have a solid understanding of objective-c and interface builder (going back to NextStep) and some PDA development experience, so I'll probably understand the answers, even if my questions are naive. I have done a bit of browsing, so I know some buzzwords.
I can't go into detail about the actual project, but I have come up with a lame analogy.
a large number of users in the same room are asked to complete task(s) in the app (say a puzzle)
they are under supervision, but the monitor cannot watch them all closely
they are not allowed to leave the application until done.
they cannot send/receive phone calls or messages during the task.
the monitor receives notification of various steps during the task
the monitor is notified when the task is completed, or the app is exited
the app sends a heartbeat, so the monitor also knows if signal is lost
Jailbreak is not an option.
The app should also work on iPod Touch.
So the things I need to do that seem dicey to me are
can I turn off (or require the user to turn off) phone and sms but still be able send http to my server
can I prevent an app from being switched out (even if, say an alarm app triggers or the phone rings).
failing prevention, can I at least detect any of these events and notify my server.
failing notification, can I record the event for the monitor to check later.
The user will be aware (and in fact welcome) these restrictions. It's a trust issue - the user must not seek help or use a helper app to solve the puzzle, and wants the monitor (and other contestants) to know that he did not. It's feasible for the user to click on an "OK, I understand and approve" screen at the beginning, but not for each communication to the server.
The app would only communicate with a central server (run by my company) - the monitor would not be able to buy the server software, and the url's of the server would not be user (or monitor) modifiable.
Hey! This looks like an app for taking exams. Not what I am doing, but that would be cool too!
EDIT --
I changed the title and am adding a few more parts to the question, based in part on mmc's answer. The App may run in an offline mode that would have to do the following:
So using the exam analogy, the user off line experience would be something like this
Launch App
App download test questions, registers start time, etc.
Turn off phone (if app can't do it by itself)
Disable any app that might interrupt my App (can app do this?)
Resume and Take Test
Indicate test done (or finish last problem).
Turn on phone (if app can't) and restart App (if needed).
App uploads test results and log of any interruptions.
So the question becomes
Am I sure that I at least get to log any interruption I can't prevent
can I know the cause of the interruption (phone answered, alarm launch, user initiated)?
can the user be prevented from modifying the log
can I know what other Apps are running when I start? (to guard against a daemon that occasionally displays a hint or something.
I would still like to run with real time uploads, so a few other ideas come to mind.
If I can reliably detect and record that the phone or another app was used, that might be almost as good as preventing it.
Can the user prevent the phone from ringing even if it's on (eg. call forward + ringer off)
Can my app know if the ringer is off
Same question for sms messaging
If I can't block it, can the user just ignore (silent) call or message and not leave my App. Would my app know that?
Sounds like you might be better off doing away with the phone, and making it exclusive to the iPod Touch.
You've nailed your trouble spots.
There is no way to disable phone functionality, and at the same time maintain network functionality of any type (3G, WiFi, or bluetooth) If you disable the phone operations with Airplane mode, all of them are disabled.
There is no way to prevent the Home button from returning you to Springboard
You can notify a server of a premature app interruption (there is an applicationWillTerminate: method on your app delegate) but is not reliable. If the operation takes too long, your app will be forcibly terminated.
You could write to the local file system that a premature interruption happened, and this would be far more reliable, as this operation would be much faster.