I have an iPhone app which communicates with a server to get the data being displayed. I have tested this app on a wifi connection and a good 3G connection. The app works without an issue. But if I test the app on a poor connection, the app crashes.
I get an XML from the server and parse it before displaying the data. I have put in the NSXMLParser method to show an alert if the parsing fails. The n/w connection code is also placed in try/catch blocks and we show an alert if the control goes to the catch block.
On a poor internet connection, the app just crashes (doesn't even go to the catch block) and checking the crash logs suggests the app could not get the complete response. Shouldn't it go to the catch block in that case? (I am using a wrapper class to make a synchronous connection)
This will always be an issue in any app using the internet if the connection is poor. Is there any way we can avoid this?
Thanks.
I am using the code provided here as the base for creating connections and getting the response
This isn't a direct answer, but may I suggest the ASIHTTPRequest library? I searched around for a long time looking for a good networking library and this seemed to be pretty bullet-proof through all sorts of connection issues.
It took me an afternoon to remove the lousy library I wrote and to integrate it. The other nice thing about it is that it can be done asynchronously.
It is available here: http://allseeing-i.com/ASIHTTPRequest/
Related
I am using NSURLConnection to communicate with a web service on my LAN. When using the Xcode Simulator everything works as expected. However, when using an iPhone the connection mostly times out (but not always).
The iPhone is connected to the LAN via wifi. I can consistently browse the web server (which is hosting the web service) using Safari.
However, the app mostly fails. It returns in the didFailWithError function reporting "The request timed out".
The app will intermittently succeed (behaving exactly as expected). I can see no pattern for success or failure. It may fail several times and then succeed and then fail again (without restarting the app). I estimate a 90%+ failure rate.
The web service always receives the request and always responds. It appears the failure happens with the device not receiving or handling the response.
I can see no obvious problem with my network. Certainly there is no IP address clash.
I am completely new to apps, Apple, Xcode and iPhone. So this could be something really very obvious to you. Any ideas what I could look at to resolve this?
The environment I'm currently using for development is as follows:
Mac OS X (10.7.4)
Xcode 4 (targetting 4.3)
iPhone 3GS (5.1.1)
Obviously I cannot give you the absolute answer, but can hopefully help you track the problem down.
First, you want vet your web service. Put a JPEG image in a public Dropbox folder. Now try to download that image with your code as well as view it with Safari. If Safari works but your code does not, then you know your code is the problem.
If both fail then the phone may have a bad transceiver, or your WIFI network may be flakey. Take the phone to some public WIFI location and redo the test. If both still fail on a second network, the phone is probably defective.
If in all cases Safari works but your code does not, then please post as much of your code as possible. Also, if using the asynchronous interface, are you getting redirected? Asked for credentials? Etc. I would be inclined to add every NSURLConnection delegate method and at least add a log so you know what's going on - that is log all responses. You can also get the html return code from the response:
assert([response isKindOfClass:[NSHTTPURLResponse class]]);
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
htmlStatus = [httpResponse statusCode];
if(htmlStatus != 200) NSLog(#"Server Response code %i", htmlStatus);
I am using a third party framework, which in rare cases does not respond anymore, if the internet connection is lost. My tests showed that when I am connected via WiFi on my home network and I start using the app and when the network changes from WiFi to the carrier network, the thread does not respond, if it was exchanging data at that very moment.
Of course I got in touch with the vendor of the framework to fix this, however, it will take some time, until I will get the patch.
In the meantime I would like to implement a work-around, so the user does not have to deal with a non-responding app, especially as this is a no-go for the app approval.
My question: Is there a way I can monitor such a thread and terminate it after a timeout?
Or would anyone have another solution approach for this issue? I know about the reachability framework of Apple, but as far as I understand the framework, it is a detection tool only, which in my case would not solve my issue, right?
Thanks, René
I am using NSURLConnection to load data from server. So, in my Iphone Application had a button, when click on this button and internet connection is connected, the data will be loaded successfully. But later when I switched off the internet connection on Mac, and then click on that button again, the didFailWithError method does not invoked but other methods such as didReceiveResponse, connectionDidFinishLoading was get called.
Anyone encountered this kind of problem before? Or anyone know the reason of this problem?
Really appreciate for any comments, suggestions and solutions. Thanks.
Before changing any line in your code, try the same test with 4.3 simulator and then 5.0.
I've tried something similar (request to URL and connection is closed with no response), and using 4.3, didFailWithError is called. In 5.0, I get a didReceiveResponse with a status code 200 OK (!) and then connectionDidFinishLoading. Same code, same request, different OS versions...
Strange behavior especially because you turned internet off, but delegate still called for ** connectionDidFinishLoading** how this is possible? Also you wrote what "when click on this button and internet connection is connected" your code still initiated connection without internet?
It's possible, what you configured using of cached data and thats why you got strange behavior like this.
*nix systems by default have timeout for connection on BSD sockets which may don't tell you nothing about what connection is missed. But i think Mac OS/iOS configured for this kind of case.
Every so often, my iPhone app gets into a state where network requests always time out, even if other apps work fine (and can even access the same sites). This isn't obviously correlated with changes in network availability, and happens both on 3G and over WiFi. Any suggestions on how to diagnose the problem?
(FWIW, the app uses MonoTouch and HttpWebRequest, but I suspect whatever's going wrong is lower-level.)
Note: The problem persists through backgrounding the app and changing the network configuration; the only fix seems to be to kill the app and re-launch it.
Updates: I've tried making use of Reachability, but to no effect. Reachability.InternetConnectionStatus always returns ReachableViaWiFiNetwork (or ReachableViaCarrierDataNetwork, depending; likewise IsHostReachable() always returns true. Runtime.StartWWAN() seems to make no difference.
There was a bug open about this at https://bugzilla.novell.com/show_bug.cgi?id=555439 and there were several attempts at resolving it. As of the last comment in the bug, it was presumed fixed but I guess if you are using MonoTouch 4.0.3 then there some cases that are not worked around.
Basically, the problem is reflected in this other Stackoverflow question: iPhone 3G Connection Enabling
What MonoTouch does to try and work around this issue is to call MonoTouch.Runtime.StartWWAN(Uri) which opens a dummy connection to the uri using an NSUrlConnection to force-wake the network interface. Then, MonoTouch goes back to using the BSD socket API inside the HttpWebRequest.
Try setting the timeOutInterval property of the NSURLRequest used to make the call.
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.