使用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* totalData;
- (void)viewDidLoad
{
[super viewDidLoad];
NSString* str = @http://www.crazyit.ory/ethos.php;
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 = content;
}
@end
|
|||
|
上面程序中的第1行红色字代码创建了一个NSURLRequest对象,第2行红色字代码以NSURLRequest对象为参数,以该视图控制器本身作为delegate,创建了NSURLConnection对象,创建该对象即可向远程服务器发送请求。 由于程序制定使用视图控制器本身作为NSURLConnection的delegate,因此该视图控制器实现了NSURLConnectionDataDelegate协议,并实现了该协议中几个特定的方法。 随着服务器响应的到来,NSURLConnection的delegate对象的如下方法依次被调用
|
使用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
2
3 @implementation ViewController
4
5 NSMutableData* totalData;
6
7 - (void)viewDidLoad
8
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 [request 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 = content;
140
141 }
142
143 @end
|
|
上面程序的关键在于红色字代码部分,该红色字代码设置了发送POST请求,而且将一个形如”name = crazyit.org&pass=疯狂软件”的字符串转换成NSData后作为请求参数,并根据请求参数设置了两个请求头的值-----这样就得到了一个带请求参数的NSMutableURLRequest |