网络请求有GET请求和POST请求,get和post实现的时候可以选择同步或者异步实现.看一个请求是GET还是POST就看网址后面有没有携带请求体.
GET与POST 区别
1.get请求 请求的网址全部明文显示 安全性不高
2.get请求 请求的网址 有字符数的限制 大概255个
3.post请求 请求的网址 不光是有一个请求的网址 还可以携带请求体 这个请求体 是以NSData形式存在 安全性较高
4.post请求没有字符数的限制
GET同步和GET异步
同步请求是在请求数据的时候不能做其他事情 异步请求在请求数据的时候可以做其他的事.
GET同步请求的步骤
1.创建一个网址对象
1 NSString *oldUrl = kSearchURL;
注意:如果你请求的网址中带有中文 必须进行重新编码
NSString *newUrl = [oldUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
然后把字符串变成一个网址对象
NSURL *url = [NSURL URLWithString:newUrl];
2.发出一个网络请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:(NSURLRequestUseProtocolCachePolicy) timeoutInterval:30.0];
CachePolicy 缓存策略 一般选默认策略 timeoutInterval 请求超时时间 默认就是get请求 如果你要设置的话 需要是可变请求
3.设置请求类型
[request setHTTPMethod:@"GET"];
4.建立链接 接收二进制数据
NSURLResponse *response = nil; NSError *error = nil; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
Response 服务器返回的 描述服务器的数据 error 链接错误信息 如果你不需要 描述服务器的数据和错误信息 可以填nil
然后可以把请求下来得数据转换成json格式
NSMutableDictionary *dataDic = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableContainers) error:nil]; NSLog(@"%@", dataDic);
GET异步请求步骤跟同步请求的前三步都是一样的,区别主要是建立链接
第一步也是创建网址对象 然后利用网址对象创建一个请求类型为GET
GET请求有两种方法 1.代理方法 2.block方法
异步代理方法需要遵守一个协议NSURLConnectionDataDelegate,为了方便使用可以把链接声明成一个属性
NSURLConnection * connection;
self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
开启异步请求
[self.connection start];
具体代码如下:
@interface GetViewController ()<NSURLConnectionDataDelegate, NSURLConnectionDelegate> // 声明一个可变的 data 用于拼接完整的方法 @property (nonatomic, retain) NSMutableData *data; // 声明一个链接属性 用于终止网络请求 @property (nonatomic, retain) NSURLConnection *connection; @end @implementation GetViewController - (void)dealloc { // 如果本页面被销毁 那么要终止网络请求 [_connection cancel]; [_data release]; [_connection release]; [super dealloc]; } #pragma mark — NSURLConnectionDataDelegate 4个代理方法 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { // 触发方法 链接成功 初始化 可变data self.data = [NSMutableData data]; NSLog(@"接收到服务器数组, 说明 链接成功"); } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { // 拼接data [self.data appendData:data]; NSLog(@"接收数据时触发"); } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { // 该方法触发 证明data已经完整 // 接下来 可以解析数据 NSMutableDictionary *dataDic = [NSJSONSerialization JSONObjectWithData:self.data options:(NSJSONReadingMutableContainers) error:nil]; NSLog(@"%@", dataDic); NSLog(@"已经完成加载"); } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog(@"查看错误信息"); } #pragma mark -异步请求block方法 // 异步请求block方法 // 建立一个异步请求链接 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { NSLog(@"%d", [NSThread isMainThread]); // 异步请求相当于 开启一个子线程去加载数据 // 数据加载完成 调用block 回到主线程 }];
POST异步跟get方法类似 有代理方法和block方法 代理方法和block方法前三步是一样的
//1.创建网址对象 NSURL *url = [NSURL URLWithString:kNewsListURL]; //2. 利用网址对象 创建一个可变请求 NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0]; //3.设置请求类型 [request setHTTPMethod:@"POST"]; // 注意 :给这个请求 携带一个请求体 NSData *pramData = [kNewsListParam dataUsingEncoding:NSUTF8StringEncoding]; // 携带到请求体 [request setHTTPBody:pramData]; // 利用这个请求 创建一个链接 并得到返回的数据 NSURLResponse *response = nil; NSError *error = nil; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; // 解析数据 NSMutableDictionary *dataDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; NSLog(@"%@", dataDic); POST异步跟get方法类似 有代理方法和block方法 代理方法和block方法前三步是一样的 // 创建网址字符创 创建网址对象 NSURL *url = [NSURL URLWithString:kNewsListURL]; // 利用网址对象创建请求 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0]; // 设置请求的类型 [request setHTTPMethod:@"POST"]; // 给这个请求 携带请求体 NSData *pramData = [kNewsListParam dataUsingEncoding:NSUTF8StringEncoding]; [request setHTTPBody:pramData]; // 利用block方法完成一步请求 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { // data就是请求完成的数据 解析就可以了 NSMutableDictionary *dataDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; NSLog(@"%@", dataDic); 利用请求创建链接 利用代理方法 实现一步请求数据 self.connection = [NSURLConnection connectionWithRequest:request delegate:self]; // 开启链接 [self.connection start]; #pragma mark - 代理方法 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { // 初始化 data self.data = [NSMutableData data]; NSLog(@"返回服务器信息, 证明链接成功了"); } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { // 拼接data [self.data appendData:data]; NSLog(@"每次返回一点数据 多次执行"); } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSLog(@"%@", self.data); NSLog(@"完成请求 此时可以进行 数据解析"); } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog(@"返回错误信息"); } #import "PostViewController.h" @interface PostViewController ()<NSURLConnectionDataDelegate, NSURLConnectionDelegate> // 声明一个可变data 进行异步请求 @property (nonatomic, retain) NSMutableData *data; // 声明成属性 在界面被销毁时 终止请求 @property (nonatomic, retain) NSURLConnection *connection; @end @implementation PostViewController - (void)dealloc { [_connection cancel]; [_connection release]; [_data release]; [super dealloc]; }
网络请求代码有很多重复代码 我们可以自己封装一下.我个人感觉封装有点类似数学中提取公因式,把相同的地方写一个方法,然后给不同的参数
封装网络请求可以想一下什么东西是外边给的,什么事里面封的.写的有点多了,封装就留给朋友吧.