NSMutableURLRequest实现Post请求及其timeoutInterval不生效问题解决

首先转载实现:http://blog.csdn.net/like7xiaoben/article/details/8735390


NSData *bodyData = [[bodyString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]dataUsingEncoding:NSUTF8StringEncoding];//把bodyString转换为NSData数据
NSURL *serverUrl = [[NSURL URLWithString:RequestUrl] URLByAppendingPathComponent:urlStr];//获取到服务器的url地址
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:serverUrl
                                                       cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
                                                   timeoutInterval:10];//请求这个地址, timeoutInterval:10 设置为10s超时:请求时间超过10s会被认为连接不上,连接超时

[request setHTTPMethod:@"POST"];//POST请求
[request setHTTPBody:bodyData];//body 数据
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];//请求头
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];//异步发送request,成功后会得到服务器返回的数据
//返回的数据 根据系统的不同会返回不同编码的数据,比如windows 为GBK,Ubuntu 为UTF8.。。
//注意转换编码格式

上面的代码中,

以下转载自:http://www.2cto.com/kf/201201/117185.html

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.address                                                                                               cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
                                                                                                  timeoutInterval:self.defaultTimeout];

timeoutInterval  已经没有了作用。不管是同步还是异步。

这个问题只有在3.0以及之后的os中才有的,而且只有在当调用了setHTTPBody之后才会出现timeout失效。这个是苹果公司对URL Loading System的在OS3.0中的一个改动,不过在我看来其实这就是一个bug!在setHTTPBody之后,request的timeout会被改为 240s(这个你可以通过NSLog [request timeoutInterval]查看),苹果开发人员的解释就是通常我们自己设置的太短的timeout其实是没什么作用的,尤其对移动设备上来讲与网 络沟通需要的时间往往是比较长的,假如你的timeout是10s,在WWAN的网络环境下,可能才刚刚“bring WWAN Interface up”(不知道怎么翻译,囧)。所以自从OS 3后,如果设置了HTTP body的data,系统就会自动设置一个最低的timeout值,即240s,而且这个值都是不能被改动的,即是你自己再次设置了 timeoutInterval,你通过NSLog [request timeoutInterval]得到的还是240S!!

一种解决办法是
现在发现Timeout就是因为Post的HttpBody设置以后,Timeout自动240,修改无效,我现在采用方式,先不带httpbody请求,看看网络是否有效,ok了再post参数,貌似解决问题!,(此种方法没有尝试,理论上是可以,但是肯定有在网络正常情况但是post照样请求不上的情况。)建议还是使用简单有效的另一种方法。

另一种办法是

使用一个定时器,到了时间提示超时并对连接进行取消处理。办法比较笨,但是真的好使,示例代码如下:

 <pre name="code" class="objc">    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.address
                                                                                                                 cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
                                                                                                         timeoutInterval:self.defaultTimeout];
    NSData *bodyData = [outputBody dataUsingEncoding:NSUTF8StringEncoding];
   
    if(cookies != nil) {
        [request setAllHTTPHeaderFields:[NSHTTPCookie requestHeaderFieldsWithCookies:cookies]];
    }
    [request setValue:@"wsdl2objc" forHTTPHeaderField:@"User-Agent"];
    [request setValue:soapAction forHTTPHeaderField:@"SOAPAction"];
    [request setValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [request setValue:[NSString stringWithFormat:@"%u", [bodyData length]] forHTTPHeaderField:@"Content-Length"];
    [request setValue:self.address.host forHTTPHeaderField:@"Host"];
    [request setHTTPMethod: @"POST"];

    [request setHTTPBody: bodyData];
       
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:operation];
   
    //自定义时间超时
    [NSTimer scheduledTimerWithTimeInterval:self.defaultTimeout target: self selector: @selector(handleTimer) userInfo:operation repeats:NO];
   
    operation.urlConnection = connection;
   
    [connection release];
}

//时间超时定义
-(void) handleTimer
{
    [operationCopy connection:[NSError errorWithDomain:@"时间超时!" code:256 userInfo:nil]];
}

 

在这个handleTimer里面,还需要对连接进行取消,不然超时后返回有数据会发生错误。



现在发现Timeout就是因为Post的HttpBody设置以后,Timeout自动240,修改无效,我现在采用方式,先不带httpbody请求,看看网络是否有效,ok了再post参数,貌似解决问题!
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是iOS Objective-C实现multipart/form-data格式上传文件的示例代码: ```objective-c // 设置请求URL NSURL *url = [NSURL URLWithString:@"http://example.com/upload"]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // 设置请求方法为POST [request setHTTPMethod:@"POST"]; // 设置请求NSString *boundary = @"Boundary+0xAbCdEfGbOuNdArY"; NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary]; [request setValue:contentType forHTTPHeaderField:@"Content-Type"]; // 设置请求NSMutableData *body = [NSMutableData data]; // 添加文件数据 NSData *fileData = UIImageJPEGRepresentation(image, 1.0); if (fileData) { [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"%@\"\r\n", @"image.jpg"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", @"image/jpeg"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:fileData]; [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; } // 添加其他参数 NSDictionary *parameters = @{@"key1": @"value1", @"key2": @"value2"}; for (NSString *key in parameters) { [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"%@\r\n", parameters[key]] dataUsingEncoding:NSUTF8StringEncoding]]; } // 添加请求结束标志 [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; // 设置请求体长度 [request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[body length]] forHTTPHeaderField:@"Content-Length"]; // 设置请求体 [request setHTTPBody:body]; // 发送请求 NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { // 处理响应 }]; [task resume]; ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值