iOS网络基础
2016-05-11 16:52
585 查看
常用类
get请求
post请求
NSURLConnectionDataDelegate代理处理返回结果
同步请求和异步请求
缓存策略
1. 常用类
NSURL(地址):请求地址NSURLRequest:请求,GET请求使用
NSMutableURLRequest:可变请求,POST请求使用,NSURLRequest的可修改子类
NSURLConnection(连接):负责创建客户端和Web服务器之间的网络连接、发送NSURLRequest对象中的数据并收集来自服务器的响应
2. get请求
- (IBAction)getLogin:(id)sender{ // 1. 确定地址URL NSString *urlString = [NSString stringWithFormat:@"http://169.254.68.33/~apple/itcast/login.php?username=%@&password=%@", _userNameText.text, _passwordText.text]; // 如果有中文,需要对地址字符串进行%的UTF8转码,才可以使用 NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; // 2. 建立请求 NSURLRequest *request = [NSURLRequest requestWithURL:url]; // 3. 建立连接,设置代理 NSURLConnection * conn = [[NSURLConnection alloc]initWithRequest:request delegate:self]; // 4. "启动"连接 start [conn start]; }
3. post请求
- (IBAction)postLogin:(id)sender{ // 1. 确定地址URL NSString *urlString = @"http://169.254.68.33/~apple/itcast/login.php/"; NSURL *url = [NSURL URLWithString:urlString]; // 2. 建立请求 // 1)建立请求,是要修改请求,所以要用NSMutableURLRequest NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // 2) 建立请求超时时间 [request setTimeoutInterval:5.0]; // 3) 指定请求方法是“POST”,注意,如果是POST,必须去指定HTTP方法。 // post字符串不区分大小写,POST [request setHTTPMethod:@"post"]; // 4) 建立请求"数据体",因为要把这个数据体传送给服务器。 NSString *bodyString = [NSString stringWithFormat:@"username=%@&password=%@", _userNameText.text, _passwordText.text]; // 将生成的字符串转换成数据 NSData *body = [bodyString dataUsingEncoding:NSUTF8StringEncoding]; // 5) 把数据体设置给请求 [request setHTTPBody:body]; // 3. 建立连接,设置代理 NSURLConnection * conn = [[NSURLConnection alloc]initWithRequest:request delegate:self]; // 4. 启动连接 [conn start]; }
4. NSURLConnectionDataDelegate代理处理返回结果
NSURLConnectionDataDelegate代理用于处理一个请求的返回结果和请求的一些过程,可以理解为java中的回调方法。此代理中有以下常用的方法处理请求的返回结果:(void)connection:didReceiveResponse:(服务器开始返回数据)
(void)connection:didReceiveData: (收到服务器返回的数据,本方法会被调用多次)
(void)connectionDidFinishLoading: (数据接收完毕,做数据的最后处理)
(void)connection:didFailWithError: (网络连接错误)
(void)connection:didSendBodyData:totalBytesWritten: totalBytesExpectedToWrite:(发送数据给服务器,POST 请求使用此方法)
@interface ViewController (){ // 定义一个自由变量,用于存放从服务器返回的数据 NSMutableData *_serverData; } @end
#pragma mark - 实现代理方法,处理返回结果 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ NSLog(@"开始接受服务器的返回请求"); } // 这个方法会被多次调用,所以我们需要定义一个成员变量来记录完整的数据 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ // 做接收数据的处理——拼接处理 // 1. 来一次,加一次,来一次,加一次 // 2. 我们需要注意_serverData的初始化问题! // 3. 懒加载 if (_serverData == nil) { _serverData = [NSMutableData data]; } // 4. 追加数据 [_serverData appendData:data]; NSLog(@"中间接收的数据:%@", data); } //数据接收完毕,做数据的最后处理 - (void)connectionDidFinishLoading:(NSURLConnection *)connection{ NSLog(@"最终的数据是:%@", _serverData); // 因为回来的是一个字符串,所以,我们将数据编码成NTF8格式的字符串 NSString *string = [[NSString alloc]initWithData:_serverData encoding:NSUTF8StringEncoding]; NSLog(@"编码后的字符串是:%@", string); // 释放原来接收的数据 _serverData = nil; } // 网络请求失败 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ NSLog(@"%@", error.localizedDescription); // 网络请求失败了,有很多种可能,其中有一种可能是: // 接收到一半的时候,网断了!_serverData里面可能会有一部分不完整的数据! // 我们要清空 _serverData。 _serverData = nil; } // 发送数据给服务器,POST 请求使用此方法 (参数:发送字节长度,总字节长度,希望发送字节长度) - (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite{ NSLog(@"发送数据 %d %d %d", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); }
5. 同步请求和异步请求
使用代理的方式处理网络请求结果会存在很多问题:代理方法较多,比较分散
要处理一个请求,需要在很多地方编写代码
不利于逻辑实现、代码编写、调试、维护以及扩展
尤其当存在多个请求时会变得非常麻烦
NSURLConnection提供了两个静态方法可以直接同步或异步调用NSURLRequest,而无需通过NSURLConnectionDataDelegate获取数据 :
同步请求:
sendSynchronousRequest:request returningResponse:&response error:&error
#pragma mark - 同步登录请求 - (IBAction)syncLogin:(id)sender{ // 1. 获得登录请求 NSURLRequest *request = [self postLoginRequest]; // 2. 开始同步连接 // 同步请求需要几个参数 // 1) 请求,已经准备好了 // 2) 响应,所为响应,就是服务器给你的响应 // 3) 错误,因为网络连接有可能出错。 // 在写网络访问程序的时候,一定要有出错处理,提醒用户。 NSURLResponse *response = nil; NSError *error = nil; // 同步请求是一定返回结果才会执行下面的语句(阻塞效果) NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; // 给一个错误的请求地址,有可能会延时网络访问时间 NSLog(@"访问完成"); // 3. 获取数据 // 可能会返回什么数据? // 1) 返回请求的结果!解码!!!!!解码成我们认识的字符串 // 2) 请求出现错误! // 3) 返回空数据! if (error != nil) { NSLog(@"访问出错:%@", error.localizedDescription); return; } if (data != nil) { NSString *string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]; // 用户登录成功之后的处理 if (string.integerValue > 0) { NSLog(@"登录成功"); // 这里可以用 navigationcontroller push 出去 } else { NSLog(@"请重新输入"); } NSLog(@"返回的内容是:%@", string); } else { NSLog(@"没有接收到数据!"); } }
异步请求:
sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
// 异步登录请求 - (IBAction)asyncLogin:(id)sender{ // 1. 获得登录请求 NSURLRequest *request = [self postLoginRequest]; // 2. 异步登录请求 // 1) 第一个参数:请求,我们已经有了 // 2) 第二个参数:队列?所谓队列,就是在线程上面需要执行的任务列表 // 3) BLOCK,是一个块代码。【需要我们自己制定参数!】——翻译:完成处理,就是处理请求完成的事情 // 第1个参数:响应 // 第2个参数:数据 // 第3个参数:错误 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { // 完成的时候有可能出现的情况有哪些 // 1. 有数据 // 2. 没数据 // 3. 有错误 if (data != nil && error == nil) { // 解码 NSString *string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", string); } else if (error == nil) { NSLog(@"接收到空数据"); } else { NSLog(@"网络请求错误%@", error.localizedDescription); } }]; }
6. 缓存策略
NSURLRequest的cachePolicy属性可以设置缓存策略,这是一种内存缓存,非硬盘缓存 ;使用缓存的目的是为了使用的应用程序能更快速的响应用户输入,使程序高效的运行。有时候我们需要将远程web服务器获取的数据缓存起来,减少对同一个url多次请求;
cachePolicy支持的缓存策略包括:
NSURLRequestUseProtocolCachePolicy默认的缓存策略,要在协议的实现方法中指定缓存逻辑
NSURLRequestReloadIgnoringCacheData忽略缓存从原始地址下载
NSURLRequestReloadIgnoringLocalAndRemoteCacheData忽略本地和远程的缓存数据,直接从原始地址下载,与NSURLRequestReloadIgnoringCacheData类似
NSURLRequestReturnCacheDataElseLoad没有缓存时从原始地址下载
NSURLRequestReturnCacheDataDontLoad只使用缓存,如果不存在缓存,请求失败,适用于没有建立网络连接离线模式
NSURLRequestReloadRevalidatingCacheData验证本地数据与远程数据是否相同,如果不同则下载远程数据,否则使用本地数据
相关文章推荐
- HttpServletRequestWrapper
- Xcode启用Https
- 计算机网络之面试常考
- http get post
- AngularJs中$http发送post或者get请求,SpringMVC后台接收不到参数值的解决办法
- 攻击与防范
- HTTPS解析
- 网络模型
- okhttputils开源库的混淆配置(Eclipse)
- 攻击和防范
- Spring Bean中方法调用/http请求调用/存储过程调用实现的工具类
- 《TCP/IP详解》学习笔记-第3章 IP:网际协议
- 企业邮箱提高安全防护的解决方案
- HTTP基本认证(Basic Authentication)的JAVA示例
- 使用google的开源框架Volley,功能一:网络请求Json数据
- 如何用70行Java代码实现深度神经网络算法
- HTTPS跨域访问时,证书导致的问题
- http协议详解
- 网络编程知识(11)--DNS
- HTTP Content-type 对照表___http://tools.jb51.net/table/http_content_type