My application allows the user to download relatively large files (~120 MB) from my own dedicated server. I'm using the ASIHTTPRequest library for downloading.
It may sound weird, but everything worked fine until yesterday. I've tried downloading files countless times both from my app (on an iPad) and a Mac, and while on the Mac the download succeeds, on the iPad it randomly times out. Sometimes it goes until 100%, sometimes it reaches 30%-40% or something and then ASIHTTPRequest's downloadFailed: selector gets called. If I print out the error's localizedDescription, I get "The request timed out".
What could this mean? Could it be a problem of my app? Or a problem with my server, or my connection? I realize this could depend on several factors, so please ask me any information you need if necessary. Thanks.
I had weird network situations like timeouts on my ipad when using wifi that started after the upgrade to 4.2, but were intermittent.
Going to Settings -> General -> Reset Network settings and then reentering the wifi settings solved it for me.
(Also check that someone hasn't recently setup a new nearby wifi access point on the same channel as your network!)
Does your server have limit about the number of connections ? I encountered a problem because the number of connections are too much, then the server declines those connections. Then, they are time out.
Do you use WiFi or 3G connection? Non-WiFi connection allows to download files with maximum size of 20Mb only.
Related
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.
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 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!
In OS3.1.3, I can create 6 UIWebView in a single view to watch 6 MJPEG stream simultaneously.
For the same application, it can run in iOS4 without any code modification.
But it can only show 4 liveview feed at the same time. And I cannot send any request afterward.
Is this a limitation for iOS4 for multitasking?
Or I use some deprecated functions, and I need to replace them?
Any suggestion is helpful, and thanks in advance.
Best Regards,
Jamie Chen
My first thought is to question memory usage. I am guessing you are trying this on a 3G S, and if true, this means you have 256 MB memory. The same is true for the iPad. The iPhone 4 has 512 MB.
Have you checked to see how much memory each UIWebView/Video Stream is chewing up?
I found the reason for the problem. The connection counts is limited by Safari.
This URL can test the number of parallel connection counts.
http://www.spasche.net/files/parallel_connections/
And the connection count of Safari is 4 in iPhone4.
Now, I am looking for solution to increase the connection count.
But I am wondering if I can find out...
Are you connecting to the same host? This could be a server or firewall issue where it only allows 4 concurrent connections from one client to one host.
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:).