1

UPDATE: Apparently on iOS 5 the problem is the "Chunked-Encoding", When sending without that everything works. Seems on server that for some reason on iOS 5 the transfer never ends (on iOS 6 everything works). Anyone has a way around that?


I'm using NSURLConnection which works perfectly on iOS 6 and on simulator on same version, But when testing that on earlier devices I get response with only

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

and never with

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

Which suppose to contain my relevant data.

Here is a snippet of my code with all functions I've used (I saw that for some people removing some delegate function solved similar issue but in my case I don't have them):

-(void)establishConnection{

NSURL *url;

url = .... // Here I've set my url - it's https


self.responseData = [[NSMutableData alloc] initWithLength:0] ;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:SERVER_RESPONSE_TIMEOUT]; 

[request setHTTPMethod:@"POST"];

// More settings here //
....


//Accept-Language: ENUS
[request addValue:@"ENUS" forHTTPHeaderField:@"Accept-Language"];

// "Accept-Topic: Dictation"
[request addValue:@"Dictation" forHTTPHeaderField:@"Accept-Topic"];

// "Accept: text/plain"
[request addValue:@"text/plain" forHTTPHeaderField:@"Accept"];

//"Transfer-Encoding: chunked"
[request addValue:@"chunked" forHTTPHeaderField:@"Transfer-Encoding"];

NSMutableData *postBody = [NSMutableData data];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [NSString stringWithFormat:@"%@",[paths objectAtIndex:0]]; // Get sound directory
NSData *soundData = [NSData dataWithContentsOfFile: [NSString stringWithFormat:@"%@/%@",documentsDirectory, @"rec.wav"]]; 

[postBody appendData:soundData];
[postBody appendData:[@"\r\n" dataUsingEncoding: NSUTF8StringEncoding]];

// final boundary
//[postBody appendData:[[NSString stringWithFormat:@"--%@\r\n", stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];

// add body to post
[request setHTTPBody:postBody];

self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];

}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
// You may have received an HTTP 200 here, or not...
NSLog(@"didReceiveResponse");

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

NSString* aStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];

NSLog(@"This is my first chunk %@", aStr);

}

- (void)connectionDidFinishLoading:(NSURLConnection *)connectionV {
connectionV = nil;
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(@"Something went wrong...");

}

Please help I can't find what am I doing wrong.

Idan
  • 9,880
  • 10
  • 47
  • 76
  • 1
    Are you receiving a 200 in didReceiveResponse? – NG. May 25 '13 at 19:06
  • Nope, I get 400. Is there any difference with iOS 5 because of the https? It works perfectly on iOS 6... I'm sending exactly same parameters on both. – Idan May 26 '13 at 11:02
  • Seems like problem is with "Chunked-Encoding" on iOS 5. Please check-out my update. – Idan May 26 '13 at 12:45

1 Answers1

0

You should not set Transfer-Encoding chunked yourself. NSURLConnection will set this for you when it is appropriate.

Basically, a HTTP message requires either a Content-Length header set, or it uses chunked transfer encoding where no Content-Length header must be set.

When you set the body data as a stream via request's property HTTPBodyStream AND do NOT specify the Content-Length explicitly, NSURLConnection will automatically use chunked transfer encoding and basing its decision when the body data is finished on the stream's state (detecting EOF).

Otherwise, if you set the body data via property HTTPBody with a NSData object, you might set the Content-Length explicitly, or let NSURLConnection set it for you, based on the length of the NSData object. In that case, you don't get a chunked transfer encoding.

Otherwise, if you set your body data as a stream (say a NSInputStream which you created as a file stream) AND set the Content-Length header explicitly, NSURLConnection will NOT use chunked transfer encoding.

If possible, do set the Content-Length even for an NSInputStream, that is when you are able to know in advance how large the body is. There might be servers which have trouble or are simply not capable to parse data transmitted via chunked transfer encoding, e.g. Rails with a "simple server" like WEBrick when you send JSON or XML data. Otherwise, the web server will buffer all input data anyway.

CouchDeveloper
  • 18,174
  • 3
  • 45
  • 67