【问题标题】:Using NSURLConnection with iOS 5 doesn't work properly在 iOS 5 中使用 NSURLConnection 无法正常工作
【发布时间】:2013-05-21 02:45:25
【问题描述】:

更新:显然在 iOS 5 上,问题是“分块编码”,如果没有发送,一切正常。似乎在服务器上由于某种原因在 iOS 5 上传输永远不会结束(在 iOS 6 上一切正常)。有人有办法解决吗?


我正在使用 NSURLConnection,它在 iOS 6 和同一版本的模拟器上完美运行,但是在早期设备上测试时,我只得到响应

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

从来没有

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

假设包含我的相关数据。

这是我使用过的所有函数的代码的 sn-p(我看到某些人删除了一些委托函数解决了类似的问题,但在我的情况下我没有):

-(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...");

}

请帮助我找不到我做错了什么。

【问题讨论】:

  • 您在 didReceiveResponse 中收到 200 吗?
  • 不,我得到 400。由于 https,iOS 5 有什么不同吗?它在 iOS 6 上完美运行...我在两者上都发送完全相同的参数。
  • iOS 5 上的“分块编码”似乎有问题。请查看我的更新。

标签: ios nsurlconnection nsurlrequest nsurlconnectiondelegate


【解决方案1】:

您不应该自己设置 Transfer-Encoding 分块。 NSURLConnection 会在适当的时候为您设置。

基本上,HTTP 消息需要设置 Content-Length 标头,或者它使用无需设置 Content-Length 标头的分块传输编码。

当您通过请求的属性 HTTPBodyStream 将正文数据设置为 流 并且不明确指定 Content-Length 时,NSURLConnection 将自动使用分块传输编码并在主体数据在流的状态下完成(检测 EOF)。

否则,如果您通过属性HTTPBody 使用NSData 对象设置正文数据,您可以显式设置Content-Length,或者让NSURLConnection 根据@987654327 的长度为您设置它@ 目的。在这种情况下,您不会获得分块传输编码。

否则,如果您将正文数据设置为流(比如您创建为文件流的NSInputStream)并明确设置 Content-Length 标头,NSURLConnection 将不会使用分块传输编码。

如果可能,即使是NSInputStream,也要设置 Content-Length,即当您能够提前知道正文有多大时。可能有些服务器有问题或根本无法解析通过分块传输编码传输的数据,例如当您发送 JSON 或 XML 数据时,Rails 具有像 WEBrick 这样的“简单服务器”。否则,Web 服务器无论如何都会缓冲所有输入数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 2021-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多