iPhone 3G Connection Enabling - iphone

My application needs Internet Connection. It seems like if I keep my iPhone idle for a while it shuts down its 3G connection. Once I wake it up (slide to unlock) and run my application, it cannot connect to the Internet. I have to run Youtube or Safari first, then it gets the Internet connection, then I have to shut down Youtube/ Safari and then I can use my application to login to my service.
Could you please let me know how can I activate 3G connection from my application (so that I can use my application directly after it wakes up from the idle state and I do not have to run other applications like Youtube/ Safari?
Thanks.

To disable the idle timer, take a look at the idleTimerDisabled property of the UIApplication class.
From Apple:
The default value of this property is
NO. When most applications have no
touches as user input for a short
period, the system puts the device
into a “sleep” state where the screen
dims. This is done for the purposes of
conserving power. However,
applications that don't have user
input except for the
accelerometer—games, for instance—can,
by setting this property to YES,
disable the “idle timer” to avert
system sleep.
Important: You should set this
property only if necessary and should
be sure to reset it to NO when the
need no longer exists. Most
applications should let the system
turn off the screen when the idle
timer elapses. This includes audio
applications. With appropriate use of
Audio Session Services, playback and
recording proceed uninterrupted when
the screen turns off. The only
applications that should disable the
idle timer are mapping applications,
games, or similar programs with
sporadic user interaction.

There is obviously another better solution, but you could load a blank page with:
[NSString stringWithContentsOfUrl ... ]
The connection will be established if it is necessary.

Only NSURLConnection (and any APIs that are layered on top of it) reinitializes the data connection after waking from sleep. To reinitialize the data connection create a dummy NSURLConnection to a non-local address and cancel it right away; then the socket API will work as expected.
There is a post on the developer forums where an Apple dev explains this in detail (but I can't find it at the moment)

Are you sure you're establising the connection correctly? My application does the same using sockets and it has no problems to re-establish the connection after device sleep. Use Reachability API in SystemConfiguration framework to get notified when coverage is available and after that make your connection attempt. Note that a time period - from several seconds to couple of minutes - has to elapse after the device awakes to gain Internet connectivity, so be patient.
There is Reachability sample from Apple, search also stackoverflow for reachability and you'll find more hints how to implement it.

Actually, you get the same problem when you change the network settings on your phone between launches of the application. For instance let's say that you use the WIFI connection when you launch the app. Then you close the app and switch off the WIFI so that the device uses the carrier's network. When you relaunch the app the socket won't be able to connect unless you do the trick with the dummy NSURLConnection (or you launch the browser before lanuching the app).
Also, canceling the NSURLConnection right after initializing it (with connectionWithRequest or initWithRequest) did not work for me. Either do not cancel the request or wait some time before canceling it (e.g. with performSelector:withObject:afterDelay:).

Related

iPhone app loses internet connectivity (NSURLConnection not returning)

I'm having an issue that's incredibly hard to debug. If my app is using WiFi and it sits idle for around 30 minutes, sometimes when I wake it up, the NSURLConnection no longer responds. Requests are sent, but never return.
At first, I thought this was a memory bug with the instances being released too early and thus never returning a response. However, if I put the app in the background, go into settings, turn off WiFi so 3G is used exclusively, and return to the app, the internet connection magically comes back to life and all pending NSURLConnections return and complete.
Obviously this is an issue for people using WiFi. Is this really a WiFi issue, or am I missing something? Going to another app like Safari, using the WiFi radio and returning to my app doesn't solve the problem - connections still don't return. I've traced this with Xcode and I'm running out of ideas.
Also 'Application Uses WiFi' Info.plist flag is set to ON and this is firmware 5.1.
is 'Application Uses WiFi' the same as UIRequiresPersistentWiFi?
Update: This has nothing to do with the Wifi flag - it can die within 5 minutes. So far, I've only been able to duplicate it on my iPhone 4s with 5.1 firmware. It's not really a solution, but I'm erasing the phone to try it with a fresh install to see if that has any effect. I have verified that NSURLConnection is always called on the main thread, and set breakpoints at connection:failedWithError: and connection:didReceiveResponse:. When the connection dies, none of these return until I disable and re-enable WiFi, and then all return at once. This happens on a local server as well, and the server still returns if I ping it with a web browser.
For any others running into this issue, it's due to TestFlight v1.0 and below:
Why does NSURLConnection fail to reach the backend?
Are you actually transmitting/receiving any data through the NSURLConnection? If not, is it possible you are hitting a TCP session timeout? Seems unlikely if the problem persists on a local server, but any intervening stateful firewall/packet inspector might be casting off your TCP connection.

iPhone reachability test needed everytime a connection is to be made?

I have a app from where i hit different REST urls. one of the service is login service.
Now, do i have to use the apple rechability test everytime i want to make a connection?
I use ASIHttpRequest
No, ASIHTTPRequest will return a timeout error / a connection failure error if it can't reach the host. You can use those errors to show something to the user to tell them their login has failed.
The connectivity status of your mobile device can change very often and unforeseeably, so checking it often is advisable.
Say, for example, that you check at app startup, and find that not network is available. You go to offline mode, but then in a few minutes you could get in a WI-FI area or your 3G signal might be stronger. If you don't check it again, you lose the possibility of going to online mode.
Indeed, checking for network availability is pretty fast compared to how long a network request lasts (say: sending a login request and waiting for the response), so you can safely do the check whenever you need it according to your policy, be it at each request, every 5 minutes, or whatever.
EDIT:
about your concern as to the approval process: you should ensure that your app has a reasonable behavior when no connection it available. Simply showing an alert to the user (and not crashing) is enough for Apple, but you could also resort to disabling all your network related buttons, or whatever fits your app. The idea is that your app should not behave crazily when no connection is available.
If you want more advanced behavior, you can check reachability with each request.
You can also use the Reachability notification service (ASIHTTP-bundled Reachability includes that feature). You can find an how-to here. But in my opinion is a bit easier to just do the check when you need it. YMMV
From what I remember the reachability demo code is effectively a listener so can update a variable as the device's reachability state changes. You then need to check this variable before making a request.
Would be surprised ASIHTTP doesn't do this kind of thing already.

iPhone battery life suggestions

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!

iPhone app network communication in background

Is it possible to have an iPhone app which carries on listening for data on a port when it is sent to background by the user and if any data comes the app can show a local notification and alert the user? I know the multitasking is deliberately limited but wof it allow for that?
It can but with major caveats:
First, the system will unregister any Bonjour names you might have established.
Second, if you're bound to the WWAN, it will go down even with you listening on it (this is true even in the foreground).
Third, if your app is not doing anything else in the background (i.e., isn't registered to provide background music, location events or telephony), you must still shutdown within the time limit for background task completion or be terminated.
So, while you could bind and listen on a socket in the background, for almost all practical purposes, it's not worth doing and you should rethink your design.
This is exactly what push notifications are for. Your application doesn't listen to your server, your server tells Apple's about any notifications, and Apple's server delivers them to the user and your application if the user wants them.

Keeping wifi/3g alive for locked iphone

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.