5

I have used NSURLConnection (asynchronous) in my app which is working fine on wifi (iOS5 & iOS6). But its creating an issue with 3G. When I run my app 3G connection then I dont get any data in my didReceiveData method.

I have putted logs in my delegate methods, but while using 3G, The request is getting timed out. What can be the issue.

EDIT: On server side -> It shows that my request has been sent to server & server has also sent the response to the client.

EDIT 2:

The code which I have written is as follows.

NSURL *url = [NSURL URLWithString:@"someURL"];

NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:url     
 cachePolicy:NSURLRequestUseProtocolCachePolicy                                   
 timeoutInterval:40.0];

//[req setHTTPShouldUsePipelining:YES];

[req setValue:@"x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[req setValue:@"someValue" forHTTPHeaderField:@"Accept"];
[req setValue:@"myCrdentails" forHTTPHeaderField:@"Authorization"];
[req setHTTPMethod:@"GET"];

[[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES];

The response headers are as below

< HTTP/1.1 200 OK
< X-Powered-By: Express
< Access-Control-Allow-Origin: *
< Content-Type: text/event-stream; charset=utf-8
< Connection: keep-alive
< Transfer-Encoding: chunked
JiteshW
  • 2,195
  • 4
  • 32
  • 61
  • More importantly, is `connectionDidFinishLoading:` or `didFailWithError:` fired ? – A-Live Nov 05 '12 at 06:58
  • Yes, after my timeout interval (40.0 - 120.0) didFailWithError is getting called – JiteshW Nov 05 '12 at 07:04
  • 2
    That makes sense, here's a post a few suggestion came from Apple engineers: http://stackoverflow.com/a/12726729/792677 – A-Live Nov 05 '12 at 07:09
  • Thanks, but no success. I have tried on two differnet network carriers & also server side uses HTTP 1.1. Tried HTTPShouldUsePipelining, but no result. The issue still persist – JiteshW Nov 05 '12 at 07:53

4 Answers4

1

After struggling with this issue for hours I finally found a working solution. The NSMutableURLRequest object has a method to set whether cellular networks are allowed or not:

[req setAllowsCellularAccess:YES];

Even though the value seems to be YES by default for objects of type NSURLRequest, it solved the problem for me.

Hopefully this will help someone like me struggling with the issue and ending up on this question.

ThomasKJDK
  • 367
  • 1
  • 7
  • 17
0

try to use Reachability framework and check there if it returns false for 3G. If it does return true and you still get the timeout, try to go to sync model and see what happens. May be the connection works ok, but something intercepts your callback.

whiteagle
  • 1,158
  • 10
  • 12
  • Yes, I have added Reachability framework in my app & its returing TRUE for 3G. What is sync model, how to do that. – JiteshW Nov 01 '12 at 12:32
  • You're now using asynchronous way, handling the data within callback. Try to use some synchronous connection method (like `NSData dataWithContentsOfURL:url` ) and see if it behaves the same way. – whiteagle Nov 01 '12 at 12:37
  • I tried using synchronous -> on wifi it shows the data once time out happens & on 3g it did not even show any data. It shows empty string. I can't understand whats going worng. – JiteshW Nov 02 '12 at 07:14
  • do you use just one connection or there are many connections in queue or pool ? NSURLConnection are being pooled by iOS and if the don't get closed correctly the pool gets full and connections fail. Also, try to connect to some another server with the same code (Flickr or some RSS feeds) and see what happens. Also check you HTTP headers server-side, be sure it has pragma for caching and "updated" headers as well. – whiteagle Nov 02 '12 at 12:31
  • I have only one connection. Same code works with RSS feed(espncricinfo). There are headers in my code which I must sent to sever with my request else my request won't work. I tried using all the caching methods but all of them are not working for me – JiteshW Nov 05 '12 at 06:43
  • ok, so please post here the headers you're sending. Please be sure you send the " `keep-alive` " header. Post here the response headers as well (get them from desktop browser like Chrome or Safari accessing the very same URL with the same data). Try to play with "Agent" header. The difference between wifi and 3g connection is that with 3G you get a lot of chunks lost (poor connectivity, TTL on server may be lower than carrier's one, etc). So, the connection get stuck if not maintained. – whiteagle Nov 05 '12 at 12:08
  • Please check Edit2 in my question for headers which I have used in my code. – JiteshW Nov 06 '12 at 07:17
  • add `[req setValue:@"keep-alive" forHTTPHeaderField:@"Connection"];` and `[req setValue:@"max-age=0" forHTTPHeaderField:@"Cache-Control"];` – whiteagle Nov 06 '12 at 09:46
  • Added headers but no success :( on 3G – JiteshW Nov 06 '12 at 11:42
  • Then you will have to change `text/event-stream` to something closable, like `text/plain` or `text/html`. It seems your server can't maintain the persistant connection and with event-stream it never get flushed client-side, thats why timeouts. – whiteagle Nov 06 '12 at 11:58
0

Is this https? I wonder if there may be some SSL validation failure going on... Also have you tried querying this from curl over 3G? If the cellular carrier proxies and isn't giving you valid data, or if its IP related (black list, closed port, etc), then you might get a different response. I'd test with curl to be sure. Either from a jail broken phone, or while tethered.

0

The problem with NSURLConnection over 3g is the timeout which is out of your hand basically ,,

If you are uploading or streaming a data to the server and that data handled there and needs sometime more than NSURLConnection time threshold or the connection is too slow the connection would be closed and returns NULL data .. that because the connection goes into IDLE state...

To overcome such issue you need to make the webservice sending an empty packets "spaces" You will see that the didReceiveData invoked on each packet arrival ..

The spaces wont affect the receivedData .. in my case the response is a JSON and I use JSonKit to parse it ,,...

hopefully it will help somebody ..

M.Othman
  • 5,132
  • 3
  • 35
  • 39