网上有个公开的天气接口:天气 ,点进其中的getSupportCityDataset接口,用这个接口为例写一下iOS上的HTTP请求的写法。 这里面提供了get、post请求的格式要求。
1、get:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<span style=
"font-size:14px;"
>NSString * URLString = @
"http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx/getSupportCityDataset?theRegionCode=广东"
;
NSURL * URL = [NSURL URLWithString:[URLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSURLRequest * request = [[NSURLRequest alloc]initWithURL:URL];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if
(error) {
NSLog(@
"error: %@"
,[error localizedDescription]);
}
else
{
NSLog(@
"response : %@"
,response);
NSLog(@
"backData : %@"
,[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}
</span>
|
用字符串构建NSURL,最好在使用URLWithString的时候把原字符串进行一下UTF8转码,关于为何要转码,看下这里第一部分。然后NSURL对象构建NSURLRequest,使用NSURLConnection的同步方法,传入request对象就可以通过get方法获取数据。
这里有个NSError对象地址传入,用于做错误判断,网络的实际情况是多变的,必须要考虑请求错误的情况,否则可能导致程序奔溃。
2、post:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
NSString * URLString = @
"http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx/getSupportCityString"
;
NSURL * URL = [NSURL URLWithString:[URLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString * postString = @
"theRegionCode=广东"
;
NSData * postData = [postString dataUsingEncoding:NSUTF8StringEncoding];
//将请求参数字符串转成NSData类型
NSMutableURLRequest * request = [[NSMutableURLRequest alloc]init];
[request setHTTPMethod:@
"post"
];
//指定请求方式
[request setURL:URL];
//设置请求的地址
[request setHTTPBody:postData];
//设置请求的参数
NSURLResponse * response;
NSError * error;
NSData * backData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if
(error) {
NSLog(@
"error : %@"
,[error localizedDescription]);
}
else
{
NSLog(@
"response : %@"
,response);
NSLog(@
"backData : %@"
,[[NSString alloc]initWithData:backData encoding:NSUTF8StringEncoding]);
}
|
3、同步和异步请求:
一般网络请求都需要一段时间,哪怕数据再少、网络再好,都会有一段时间,而且很多时候必须考虑在网络不好的时候的app状态。使用同步请求只需安心等待数据就可以,不需要做额外操作,上面两例都是同步请求,connection调用方法后会把返回请求的数据,无需做什么其他事。但是同步会阻塞线程,如果通过点击button来发起请求,那么按钮会停留在highLight状态直到请求结束,会造成一种app卡住、死机的感觉,很不好。
异步get:
1
2
3
4
5
6
|
NSString * URLString = @
"http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx/getSupportCityDataset?theRegionCode=广东"
;
NSURL * URL = [NSURL URLWithString:[URLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSURLRequest * request = [[NSURLRequest alloc]initWithURL:URL];
_connection = [[NSURLConnection alloc]initWithRequest:request delegate:self]; (
1
)
|
协议方法:
要注意的是这里有两个委托:NSURLConnectionDataDelegate和NSURLConnectionDelegate,前一个继承于后一个,获取数据的方法是定义在前一个委托里面的,所以只要遵循NSURLConnectionDataDelegate就可以了。
一般用到四个委托方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<pre name=
"code"
class
=
"objc"
>
//接受到respone,这里面包含了HTTP请求状态码和数据头信息,包括数据长度、编码格式等
-(
void
)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ NSLog(@
"response = %@"
,response); _backData = [[NSMutableData alloc]init];
}
//接受到数据时调用,完整的数据可能拆分为多个包发送,每次接受到数据片段都会调用这个方法,所以需要一个全局的NSData对象,用来把每次的数据拼接在一起
-(
void
)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[_backData appendData:data];
}
//数据接受结束时调用这个方法,这时的数据就是获得的完整数据了,可以使用数据做之后的处理了
-(
void
)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(@
"%@"
,[[NSString alloc]initWithData:_backData encoding:NSUTF8StringEncoding]);
}
//这是请求出错是调用,错误处理不可忽视
-(
void
)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
if
(error.code == NSURLErrorTimedOut) {
NSLog(@
"请求超时"
);
}
NSLog(@
"%@"
,[error localizedDescription]);
}
</pre><br>
<pre
class
=
"brush:java;"
></pre>
<pre
class
=
"brush:java;"
></pre>
<p></p>
<pre
class
=
"brush:java;"
></pre>
最后,请求可以设置超时时间:<pre
class
=
"brush:java;"
>NSURLRequest * request = [[NSURLRequest alloc]initWithURL:URL cachePolicy:
0
timeoutInterval:
8.0
];</pre>或者:<pre
class
=
"brush:java;"
>NSMutableURLRequest * request = [[NSMutableURLRequest alloc]initWithURL:URL];
[request setTimeoutInterval:
8.0
];</pre>请求时间超过所设置的超时时间,会自动调用<pre
class
=
"brush:java;"
>-(
void
)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error</pre>但是有个问题是怎么把判断是超时导致的请求失败,上面的例子里已经写了,可以根据返回的error的code进行判断。了解不同情况的请求失败,可以更好的给用户提示。<br>
<br>
<p></p>
|