怎么样处理nsurlconnectnsurlsession异步请求求得到的数据

Pages: 1/3
主题 : NSURLConnection异步发送HTTP请求,得到的结果中汉字是乱码
级别: 侠客
可可豆: 1084 CB
威望: 1089 点
在线时间: 498(时)
发自: Web Page
NSURLConnection异步发送HTTP请求,得到的结果中汉字是乱码&&&
- (void)viewDidLoad {    NSString *urlString = @&/translate_a/t?client=t&text=computer&sl=en&tl=zh_CN&;        NSURL *url = [NSURL URLWithString:urlString];    NSMutableURLRequest *req=[[NSMutableURLRequest alloc]                               initWithURL:url                               cachePolicy:NSURLRequestReloadIgnoringLocalCacheData                               timeoutInterval:30.0];    receivedData=[[NSMutableData alloc] initWithData:nil];    [req setHTTPMethod: @&POST&];    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];    [req release];    [conn release];}//接收NSData数据- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {        [receivedData appendData:data];}//接收完毕,显示结果- (void)connectionDidFinishLoading:(NSURLConnection *)connection {        NSString *results = [[NSString alloc]                          initWithBytes:[receivedData bytes]                          length:[receivedData length]                          encoding:NSASCIIStringEncoding];      NSLog(results);}    //输出字符串results,为什么里面的汉字都是乱码呢?NSASCIIStringEncoding有问题吗?我换成其他几个编码方式也是有乱码!郁闷中[ 此帖被ad-12-13 15:51重新编辑 ]
级别: 侠客
可可豆: 1084 CB
威望: 1089 点
在线时间: 498(时)
发自: Web Page
把&/translate_a/t?client=t&text=computer&sl=en&tl=zh_CN&放入浏览器地址栏,得到的结果是正确的,没有乱码.但是iphone程序中就不行,
级别: 精灵王
可可豆: 25657 CB
威望: 25623 点
在线时间: 5074(时)
发自: Web Page
NSASCIIStringEncoding错了,google用的是UTF-8
级别: 侠客
可可豆: 1084 CB
威望: 1089 点
在线时间: 498(时)
发自: Web Page
我也怀疑是NSASCIIStringEncoding的问题,但是换成NSUTF8StringEncoding根本就得不到数据了我直接在didReceiveData方法中检查传入的data- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {        [receivedData appendData:data];       NSString *str=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding ];  NSLog(@&%@&,str); } //编码方式设置成NSUTF8StringEncoding,str输出是null   编码方式设置成NSASCIIStringEncoding,str输出是[[[&¼ÆËã»ú&,&computer&,&J¨¬su¨¤nj¨©&]],[[&noun&,[&¼ÆËã»ú&,&µçÄÔ&]]],&en&]
级别: 侠客
可可豆: 1084 CB
威望: 1089 点
在线时间: 498(时)
发自: Web Page
本人也是初学这个问题很无语,一下午都不能解决!
级别: 侠客
可可豆: 1396 CB
威望: 1335 点
在线时间: 1025(时)
发自: Web Page
把一楼的方法改一下到UTF-8,再结合二楼的方法就可以了
级别: 新手上路
可可豆: 200 CB
威望: 200 点
在线时间: 48(时)
发自: Web Page
看上去这段代码没有错,应该可以工作。NSString *str=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding ];所以我试了你的代码,的确会失败,返回的NSString指针是nil。原因是NSURLConnection发起的连接,Google这边返回的编码是GB2312。所以要能得到NSString,需要的代码是:NSString *results = [[NSString alloc] initWithData:receivedData encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_)];18030是国标2312的超集,所以读的时候,用2312的地方改用18030基本是没错的。有这个差异的原因应该是浏览器和NSURLConnection发出的请求,在HTTP HEADER上有差异。如果你在用NSURLConnection发请求前,设定HTTP HEADER,让网站返回UTF-8编码的内容,再统一用UTF-8处理会比较好。大概试了下,如果设一下User-Agent头,网站就会返回UTF-8编码,但是具体的情况还要你自己调研一下。[req setValue:@&AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5& forHTTPHeaderField:@&User-Agent&];另外,这和异步/同步无关。发出的HTTP请求不同,得到的内容编码不同。
级别: 精灵王
发帖: 1336
可可豆: 8605 CB
威望: 8601 点
在线时间: 2072(时)
发自: Web Page
有的网站用gzip压缩网页传输的,还可能不是UTF-8的编码方式引起的,需要区别对待,很麻烦的。
级别: 侠客
可可豆: 1084 CB
威望: 1089 点
在线时间: 498(时)
发自: Web Page
引用 引用第6楼weipin于 21:36发表的  :看上去这段代码没有错,应该可以工作。NSString *str=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding ];....... 感谢6楼朋友的回答,问题解决了!回答得很明白,我这样的新手受益匪浅.[ 此帖被ad-09-19 09:05重新编辑 ]
级别: 精灵王
可可豆: 7331 CB
威望: 7331 点
在线时间: 300(时)
发自: Web Page
受教受教,学习了。。。。。。。。
Pages: 1/3
关注本帖(如果有新回复会站内信通知您)
苹果公司现任CEO是谁?2字 正确答案:库克
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版搜索 新闻 资讯 游戏
您现在的位置:&&>>&&>>&&>>&&>>&正文
[常见问题]iPhone&NSURLConnection&delegate&methods得不到调用
编辑:plus && 来源:net && 发布时间: 17:13:18
当你使用NSURLConnection异步模式时,比如代码如下:
NSString&*url = [NSString&stringWithFormat:@"/...",...];
url = [url&stringByAddingPercentEscapesUsingEncoding:&NSUTF8StringEncoding];
NSURLRequest&*request = [NSURLRequest&requestWithURL:[NSURL&URLWithString:url]];
connection&= [[NSURLConnection&alloc]&initWithRequest:request&delegate:self];
并实现了NSURLConnection的代理方法:
#pragma mark NSURLConnection delegate methods
// The following are delegate methods for NSURLConnection.
- (void)connection:(NSURLConnection&*)connection didReceiveResponse:(NSURLResponse&*)response {
- (void)connection:(NSURLConnection&*)connection didReceiveData:(NSData&*)data {
- (void)connectionDidFinishLoading:(NSURLConnection&*)connection {
但是你发现代码方法永远执行不到。
原因一般是因为这些方法是在一个单独线程中执行,需要一段时间来处理网络数据。
而在此之前你可能在别处退出了该线程。
为了避免这种情况,通常你可以在发送URL请求后,等待数据处理完成再做下一步的事情,这样就可以和主线程或其它线程同步:
while(!finished) {
[[NSRunLoop&currentRunLoop]&runMode:NSDefaultRunLoopMode&beforeDate:[NSDate&distantFuture]];
- (void)connectionDidFinishLoading:(NSURLConnection&*)connection {
finished&=&TRUE;
扫描左侧二维码,可以订阅iPhone中文网官方微信。每天除了推送最新的苹果产品资讯,我们还将不定期举行有奖活动,广大网友可以积极参与,幸运随时会降临!当然,你也可微信搜索“iPhone中文网”或“apple4cn”,关注iPhone中文网官方微信,第一时间获取更多苹果资讯。
iOS越狱破解
苹果产品信息查询
热门新闻排行
皖公网安备05 皖网文许字[3号
TGBUS Corporation, All Rights Reserved随笔 - 53&
文章 - 0&评论 - 0&trackbacks - 0
第一步:遵守协议NSURLConnectionDataDelegate
第二步:创建包含请求网址的NSURL类型的对象
NSURL * url = [NSURL URLWithString:PATH];
第三步:创建NSURLRequest请求
NSURLRequest * request = [NSURLRequest requestWithURL:url];
第四步:将request对象赋给NSURLCon对象开始异步请求
&[NSURLConnection connectionWithRequest:request delegate:self];
异步请求代理中3个重要的协议方法
//&1&接收服务器的响应
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
NSLog(@"接收服务器的响应");
//-----------------拓展
//判断当前服务器的响应状态
200表示数据请求成功
404表示请求的数据不存在
400 表示客户端请求的语法发生错误
500 服务器端语法发生错误
//NSURLResponse
所有响应对象的父类 其实两个设备之间通信一定要遵守http协议 所以这里的响应对象为NSHTTPURLRequest
NSHTTPURLResponse * httpRequest = (NSHTTPURLResponse *)
NSInteger status = [httpRequest statusCode];
NSLog(@"%d",status);//验证什么原因没有请求到数据
myData.length = 0;//在数据请求下来之前将mydata进行清空,防止对后面的内容造成影响
//NSURLConnection只能用单任务请求,不能进行多任务异步请求。另外两个可以用多任务
//多个线程并行工作请求数据请求下来的数据都不完整,只能多个线程请求的数据放在一起才算一个完整的数据,所以在这需要将各个data拼接。这也是为什么要声明一个NSMutableData的原因,从服务器中请求下来的数据都是NSdata类型的,用来承载所有线程请求的数据
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
NSLog(@"接收请求数据");
//该方法会被事实调用,直到所有数据请求结束
[myData appendData:data];//将每个线程请求下来的数据进行拼接
//数据解析
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
NSLog(@"数据请求结束");
//数据解析,解析以后将数据加到UI上
NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:myData options:NSJSONReadingMutableContainers error:nil];
NSArray * array = [dic objectForKey:@"users"];
[_dataSourse addObjectsFromArray:array];
[self.tableView reloadData];
阅读(...) 评论()iOS-----使用NSURLConnection
来源:博客园

使用NSURLConnection


如果只是为了读取HTTP等服务器数据,或向服务器提交数据,iOS还提供了NSURLConnection类,NSURLConnection使用NSURLRequest向远程服务器发送同步或异步请求,并获取服务器响应的数据。除了NSURLRequest之外,还可使用NSMutableURLRequest向服务器发送数据。

使用NSURLConnection从网络获取数据

NSURLConnection可用于根据URL加载服务器响应,该对象的方法并不多,如果使用该对象来异步加载服务器响应,则需要为该对象指定一个遵守NSURLConnectionDelegate协议的对象,该对象作为NSURLConnection的delegate,负责处理异步加载过程中的事件。
除此之外,还可使用NSURLConnection的sendSynchronousRequest:returningResponse:error:类方法同步架子啊服务器响应。
NSURLConnection大致提供了如下常用的方法。
 

- (NSURLRequest *)originalRequest: 获取该NSURLConnection最初的NSURLRequest对象的深拷贝


- (NSURLRequest *)currentRequest: 返回该NSURLConnection当前使用的NSURLRequest对象


采用同步请求的方式获取网络数据的方法如下


+ sendSynchronousRequest:returningResponse:error:第1个参数代表发送请求的NSURLRequest对象;第2个参数需要传入NSURLRequest对象的指针,用于获取服务器响应对象;第3个参数用于保存获取的错误信息。

采用异步请求的方式获取网络数据的方法如下

+ connectionWithRequest:delegate::采用异步请求的方式获取数据。第2个参数作为NSURLConnection的delegate。


- initWithRequest:delegate: : 与上一个方法基本相同,只是该方法是实例方法,必须先调用alloc,再调用该方法


- initWithRequest:delegate:startImmediately:: 与前一个方法的功能基本相似,只是多了一个startImmediately参数,该参数控制是否立即发送请求


+ sendAsynchronousRequest:queue:completionHandler: : 该方法需要额外指定NSOperationQueue参数,表明将请求交给指定的NSOperationQueue处理.


-
start: 开始发送请求.只是当通过- initWithRequest:delegate:startImmediately:方法发送请求,且最后一个参数为NO时,才需要调用该方法。


使用NSURLConnection从网络获取数据的步骤如下


1.
创建NSURLRequest对象,该对象代表对远程服务器的请求。该对象可以包括请求的URL、缓存策略、超时时长等信息。
2.
调用NSURLConnection的实例方法或类方法,以NSURLRequest对象为参数创建NSURLConnection即可发送请求。
3.
如果调用方法以异步方式加载服务器响应,则需要为NSURLConnection对象指定delegate对象,因此还需要为delegete对象实现特定的方法。


代码片段



ViewController.m

@implementation ViewController

NSMUtableData* totalD

- (void)viewDidLoad

{

[super viewDidLoad];

NSString* str = @http://www.crazyit.ory/ethos.

 totalData = [[NSMutableData alloc] init];

// 以指定NSString创建NSURL对象

 NSURL * url = [NSURL URLWithString:str];

 // 创建NSURLRequest对象

// NSURLRequest* request = [NSURLRequest requestWithURL:url];

// 通过这种方式创建的NSURLRequest可以指定缓存策略、超时时长

NSURLRequest* request = [NSURLRequest requestWithURL:url

cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:5];

// 以指定URL、delegate创建连接、发送请求

NSURLConnection* conn = [NSURLConnection
connectionWithRequest:request delegate:self ];

// 如果conn为nil,则直接返回

if(conn !=nil)

{

return;

}

}

//
当服务器响应生成时激发该方法

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

{

NSLog(@”++didReceiveResponse++”);

NSLog(@”响应的数据类型:: %@” , response.MIMEType);

// 获取响应数据的长度,如果不能检测到长度,则返回NSURLResponseUnknownLength(-1)

NSLog(@”响应的数据长度为: %lld”,
response.expectedContentLength);

NSLog(@”响应的数据所使用的字符集: %@”, response.textEncodingName);

 NSLog(@”响应的文件名: %@”, response.suggestedFilename);

}

// 每次读取服务器响应的数据时,都会激发该方法

// 对于一个请求而言,服务器数据可能要分几次才能读取,因此该方法将会被处罚多次

// 如果程序需要将这些数据转换成字符串,则建议使用NSMutableData来收集这些数据.然后整体转换

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

{

[totalData appendData:data];

}

// 当连接服务器出现错误时激发该方法.可通过error获取错误信息

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

{

NSLog(@”++error++”);

}

// 当数据load完成时激发该方法.对于每次请求,该方法只会被激发一次

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

NSLog(@”++finishLoading++”);

NSString* content = [[NSString alloc] initWithData:totalData

encoding:NSUTF8StringEncoding];

// 清空所有数据

[totalData
setLength:0];

self.showView.text =

}

@end

 


上面程序中的第1行红色字代码创建了一个NSURLRequest对象,第2行红色字代码以NSURLRequest对象为参数,以该视图控制器本身作为delegate,创建了NSURLConnection对象,创建该对象即可向远程服务器发送请求。
由于程序制定使用视图控制器本身作为NSURLConnection的delegate,因此该视图控制器实现了NSURLConnectionDataDelegate协议,并实现了该协议中几个特定的方法。
随着服务器响应的到来,NSURLConnection的delegate对象的如下方法依次被调用

1.
connection:didReceiveResponse: 当服务器响应到来时,激发该方法
2.
connection: didReceiveData: 每次读取服务器响应的数据时,都会激发该方法.对于一个请求而言, 服务器数据可能要分几次才能读取, 因此该方法将会被触发多次.
3.
connectionDidFinishLoading: 服务器响应读取完成时激发该方法.

 
 
 

 

使用NSMutableURLRequest向服务器发送数据

NSMutableURLRequest不仅可以添加请求头,还可以添加请求参数,这样即可向服务器发送数据了.

NSMutableURLRequest新增了如下常用方法


- addValue:forHTTPHeaderField: 该方法用于为NSMutableURLRequest添加请求头


- setAllHTTPHeaderFields: 该方法通过一个NSDictionary一次性地为NSMutableURLRequest设置多个请求头


- setHTTPBody: 设置NSMutableURLRequest的请求体数据-----也就是设置请求参数


- setHTTPBodyStream: 以NSInputStream为参数设置NSMutableURLRequest的请求体数据.该方法与setHTTPBody方法只能设置一个


-
setHTTPMethod: 设置提交请求的方式,要么是POST,要么是GET, 默认是GET.


-
setHTTPShouldHandleCookies: 设置该HTTP请求是否处理Cookie.


-
setValue:forHTTPHeaderField: 为指定的请求头设置请求值


代码示例



1 ViewController.m
3 @implementation ViewController
5 NSMutableData* totalD
7 - (void)viewDidLoad
9 {
 10 
 11
[super viewDidLoad];
 12 
 13
NSString* str = @”http://192.168.1.88.8888/abc/login.jsp”;
 14 
 15
totalData = [[NSMutableData alloc] init];
 16 
 17
// 以指定NSString创建NSURL对象
 18 
 19
NSURL* url = [NSURL URLWithString:str];
 20 
 21
// 创建NSURLRequest对象
 22 
 23
// NSURLRequest* request = [NSURLRequest requestWithURL: url];
 24 
 25
// 通过这种方式创建的NSURLRequest可以指定缓存策略、超时时长
 26 
 27
NSMutableURLRequest* request = [NSMutableURLRequest
requestWithURL:url
 28 
 29 cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
 30 
 31 timeoutInterval:5];
 32 
 33 // --------------------下面代码开始设置请求参数--------------------
 34 
 35 // 准备请求参数
 36 
 37 NSString* post = [NSString stringWithFormat:@”name=%@&pass=%@”, @”crazyit.org”,
@”疯狂软件”];
 38 
 39 // 将请求参数转换为NSData
 40 
 41 NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding];
 42 
 43 NSString *postLength = [NSString stringWithFormat:@”%d”, [postData length]];
 44 
 45 // 设置请求的方式,默认发送GET请求
 46 
 47 [request setHTTPMethod:@”POST”];
 48 
 49 //
添加两个请求头
 50 
 51 [request
setValue:postLength
forHTTPHeaderField:@”Content-Length”];
 52 
 53 [request
setValue:@”application/x-www-form-urlencoded”
 54 
 55 forHTTPHeaderField:@”Content-Type”];
 56 
 57
// 将请求数据设置为HTTP请求体
 58 
 59
setHTTPBody:postData];
 60 
 61
// 以指定URL、delegate创建连接、发送请求
 62 
 63
NSURLConnection* conn = [NSURLConnection connectionWithRequest:request
 64 
 65 delegate:self];
 66 
 67 // 如果conn为nil,则直接返回
 68 
 69 if(conn != nil)
 70 
 71 {
 72 
 73
return;
 74 
 75 }
 76 
 77 }
 78 
 79 //
当服务器响应生成时激发该方法
 80 
 81 - (void)connection: (NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
 82 
 83 {
 84 
 85
NSLog(@”++didReceiveResponse++”);
 86 
 87
NSLog(@”响应的数据类型:: %@” , response.MIMEType);
 88 
 89
// 获取响应数据的长度,如果不能检测到长度,则返回NSURLResponseUnknownLength(-1)
 90 
 91
NSLog(@”响应的数据长度为: %lld”,
response.expectedContentLength);
 92 
 93
NSLog(@”响应的数据所使用的字符集: %@”, response.textEncodingName);
 94 
 95
NSLog(@”响应的文件名: %@”, response.suggestedFilename);
 96 
 97 }
 98 
 99 // 每次读取服务器响应的数据时,都会激发该方法
100 
101 // 对于一个请求而言,服务器数据可能要分几次才能读取,因此该方法将会被处罚多次
102 
103 // 如果程序需要将这些数据转换成字符串,则建议使用NSMutableData来收集这些数据.然后整体转换
104 
105 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*) data
106 
107 {
108 
109
[totalData appendData:data];
110 
111 }
112 
113 // 当连接服务器出现错误时激发该方法.可通过error获取错误信息
114 
115 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
116 
117 {
118 
119
NSLog(@”++error++”);
120 
121 }
122 
123 // 当数据load完成时激发该方法.对于每次请求,该方法只会被激发一次
124 
125 - (void)connectionDidFinishLoading:(NSURLConnection *)connection
126 
127 {
128 
129
NSLog(@”++finishLoading++”);
130 
131
NSString* content = [[NSString alloc] initWithData:totalData
132 
133 encoding:NSUTF8StringEncoding];
134 
135 // 清空所有数据
136 
137 [totalData
setLength:0];
138 
139 self.showView.text =
140 
141 }
142 
143 @end

 


上面程序的关键在于红色字代码部分,该红色字代码设置了发送POST请求,而且将一个形如”name = crazyit.org&pass=疯狂软件”的字符串转换成NSData后作为请求参数,并根据请求参数设置了两个请求头的值-----这样就得到了一个带请求参数的NSMutableURLRequest

免责声明:本站部分内容、图片、文字、视频等来自于互联网,仅供大家学习与交流。相关内容如涉嫌侵犯您的知识产权或其他合法权益,请向本站发送有效通知,我们会及时处理。反馈邮箱&&&&。
学生服务号
在线咨询,奖学金返现,名师点评,等你来互动}

我要回帖

更多关于 nsurlconnection ios9 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信