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

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.

Related

Android VoIP application: PARTIAL_WAKE_LOCK vs ignoring Battery Optimizations (doze whitelisting)

I'm working on a Voice over IP (VoIP) application using the SIP protocol which requires the application to be listening to incoming calls. This means the application must not sleep or die.
For old code, it seems the way to do this is to acquire a PARTIAL_WAKE_LOCK.
Now from Android 6.0 and higher, there's the new Doze. It is recommended that, if you don't want your app to go to standby, you should "whitelist" it by requesting the REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission. This is specifically for VoIP applications according to the documentation.
These two different things seem to be related. I'm not sure how they are related, if they interfere with each other, if I should use one or the other or both, and if there are other considerations. Please explain.
Also, I am not allowed to use Push Notifications on this project. If you have other advice for saving the battery please let me know.
In your case looks like you should be asking for whitelist, as the documentation you linked, it advises that GCM can collide with the SIP protocol. I would handle this case like a typical runtime permission. On some place of your app(the on create of your main screen for ex) ask for whitelist and the reason why you need it, if they dont want just disable functionality related to receive calls.
You should only use one of them at a time, you can always do it the hard way and handle the voip calls without sip, then you could handle incoming calls with push notifications from your server, but i dont think someone is up to that unless you need a top tier product.
There is no workaround for this, indeed the only good way is to do the heavy lifting by yourself, because its kinda popular on users to use battery optimizators / improved doze apps so you could get killed anyway.

Network reachability notification on status change is mandatory on iPhone?

Many reachability test codes seem to incorporate "notify" concept so that when network gets back on, user can get notified.
Do I need to implement the "notification" part? Is it acceptable to alert user whenever he tries something that needs network connection and it is not available? (without notification when connection gets back)
I see example codes deals with pure network availability(if the device is connected to wifi, 3g, and so on) and with reachability to specific ip. My app needs to connect to specific ip address when appropriate. In this scenario, just alerting if that ip is not reachable in appropriate times are all that's required or do I need to handle something more?(such as putting different messages for alerting user to turn on network and for alerting user that my ip is not reachable)
Thank you
1.
I'd recommend taking a look at Andrew Donoho's Reachability class that is an extension of the sample released by Apple:
http://blog.ddg.com/?p=24
That'll abstract away the need to worry about handling the notifications and allow you to focus on simply testing the reachability of your IP or if a certain network type is active.
2.
In terms to actual notification to the user, I'd say that depends on your application. For instance on the vast majority of the screens on one of my Apps the UIView attempts to do an async download of data from a RESTful service when that view loads. I don't do any reachability tests beforehand, I simply attempt to make the call and if the request fails, I notify the user after the fact. Unless you have a specific case of needing to know an IP is reachable, I'd think in the general case handling any errors on connections attempts should be sufficient. I'm sure there are are plenty of edge cases though that you might want to test reachability first.
On the other hand I do use the reachability on a given screen that I recommend a WiFi connection. Since that screen performs a fairly data intensive sync, I warn the user if they are on 3G that the sync make take quite a bit longer vs. WiFi simply performs the sync.
AFAIK, there is no requirement that you pop up a notification when the network becomes available, or in fact that you actually pop up a notification when the network is not available. You could instead enable/disable network-related buttons (as long as the user can know why the buttons are disabled), display an unobtrusive on-screen indicator, or whatever.
The important part is that you do not display a blank screen or a cryptic error message when the network is not available, or otherwise leave the user wondering why things aren't working.
I don't know of any requirement that you differentiate between "networking off" and "networking on but IP address unreachable".

Which type of "No Network Connectivity" warning should I use for my iPhone App

The app i'm developing for the app store infrequently needs network connectivity. I've already implemented a way to handle/notify the user when there is no network connection, but that only happens when they've initiated the request (click a button to make a web service call).
My question is, Does apple require a continuous check for network connectivity, i.e. their reachability example, or will the method I have implemented (checking for network connectivity only when certain actions are triggered) be acceptable for app store submission?
Thanks in advance.
Checking for connectivity only when it's needed is sufficient. In fact, Apple discourages using Reachability as a "pre-flight" check. They say to just handle failure gracefully, and then use Reachability if necessary to watch for connectivity to come back.
It is acceptable for app store submission. In fact, I'm sure AT&T and Apple would prefer it.

iphone 3g network problem

does the code for checking network availability works well with 3g.(provided it works fine with wifi and 2g). Whether i should send the message to the destination and then show the error or first check for network availability.
I don't have experience from the iPhone, but in general detecting network presence is hard. It can change within a very short time since you last tested it, so any result from the test will still be unreliable.
I would suggest trying to send the data, if it's something you (or the user) want to send out anyway, there is no loss in trying. It's better to try, and get a failure from e.g. TCP (having done retries automatically as usual), than to decide at a single moment that sending is impossible.
I would suggest reading through this best practices guide, and then studying the Reachability example source code. That is the "apple prescribed" approach.

iPhone 3G Connection Enabling

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:).