转载请标明出处:

http://blog.csdn.net/xmxkf/article/details/51376048

本文出自:【openXu的博客】

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 验证本地数据与远程数据是否相同,如果不同则下载远程数据,否则使用本地数据

iOS网络基础的更多相关文章

  1. iOS网络基础知识

    iOS网络基础知识 1.一次HTTP请求的完整过程 (1)浏览器或应用发起Http请求,请求包含Http请求Http(请求),地址(url),协议(Http1.1)请求为头部 (2)web服务器接收到 ...

  2. iOS网络基础---iOS-Apple苹果官方文档翻译

    CHENYILONG Blog iOS网络基础---iOS-Apple苹果官方文档翻译 iOS网络基础 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http: ...

  3. iOS基础 - iOS网络基础

    一.网络访问的四个步骤 l 第一步:确定地址URL l 第二步:建立请求 l 第三步:建立并启动连接 l 第四步:连接完成,处理结果 备注:URL,统一资源定位符(URL,英语Uniform Reso ...

  4. (五十九)iOS网络基础之UIWebView简易浏览器实现

    [UIWebView网络浏览器] 通过webView的loadRequest方法可以发送请求显示相应的网站,例如: NSURL *url = [NSURL URLWithString:@"h ...

  5. IOS开发基础知识碎片-导航

    1:IOS开发基础知识--碎片1 a:NSString与NSInteger的互换 b:Objective-c中集合里面不能存放基础类型,比如int string float等,只能把它们转化成对象才可 ...

  6. IOS开发基础知识--碎片31

    1:UITableViewCell drawInRect 在iOS7中失败 解决办法,把Cell里的布局移到新建的View里面,在View里面实现DrawInRect,然后在Cell里面加载View, ...

  7. 【读书笔记】iOS网络-使用Game Kit实现设备间通信

    Apple的Game Kit框架可以实现没有网络状况下的设备与设备之间的通信,这包括没有蜂窝服务,无法访问Wi-Fi基础设施以及无法访问局域网或Internet等情况.比如在丛林深处,高速公路上或是建 ...

  8. 【读书笔记】iOS网络-底层网络

    在iOS上,有一个库叫做Core Foundation networking或CFNetwork,它是对原始Socket的轻量级封装,不过它很快对于大多数常见场景来说变得非常笨重了.最后,添加了另一层 ...

  9. 【读书笔记】iOS网络-Web Service协议与风格

    协议指的是在与其它系统交换结构化信息时所要遵循的一套格式,过程与规则.此外,协议定义了在传输过程中所要使用的数据格式.这样,接收系统就能正确地解释结构化信息并做出正应的回应. 1,简单对象访问协议. ...

随机推荐

  1. 【JAVA】pdf转图片

    最近java项目中使用到了pdf转图片的需求,在此记录一下. 1.基于GhostScript p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px ...

  2. [JS]手动实现一个横屏滚动公告js插件

    前言 工作中要用到.在github上找的大部分都是竖屏滚动没办法只能自己手动写. 本来只是想随便实现一下的,结果一时兴起把它弄成了一个简单的小插件,开了个github仓库(希望路过点个星) JS横屏滚 ...

  3. Java IO(三)

    在Java IO提供的类中,除了前面介绍的RandomAccessFile类之外,还有一系列的io操作类. 主要分为两大类.字符流和字节流.关系图如下: 在Java IO的操作中,很好的体现了Java ...

  4. [HNOI 2015]菜肴制作

    Description 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高到低给予 1到N的顺序编号,预估质量最高的菜肴编号 ...

  5. [SHOI2011]双倍回文

    Description   Input 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. Output 输出文件只有一行,即:输入数据中字符串的最长 ...

  6. HDU3311Dig The Wells

    给定N个寺庙,和M个另外的地方. 然后给定点权,表示在这个点挖水井需要的代价. 再给定边权,为建造无向边i,j的代价. 然后求怎样弄最小的代价使得前N个点,就是寺庙都能从挖的井里得到水. 输入输出格式 ...

  7. ●UOJ 21 缩进优化

    题链: http://uoj.ac/problem/21 题解: ...技巧题吧 先看看题目让求什么: 令$F(x)=\sum_{i=1}^{n}(\lfloor a[i]/x \rfloor +a[ ...

  8. 洛谷mNOIP模拟赛Day1-分组

    传送门 首先是贪心的思路 从后向前选,能多选就多选, 理由:数字越少肯定越优,同时间隔尽量向前推,字典序尽量小 对于K==1,枚举1~512直接判断 对于K==2,需要用镜像并查集,来刻画" ...

  9. 2393Cirno的完美算数教室 容斥

    2393: Cirno的完美算数教室 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 652  Solved: 389[Submit][Status][ ...

  10. salt基本使用之一(1)

    1.帮助文档 以cmd函数为例子说下salt中的一些帮助信息 # 查看指定modules用法 salt '*' sys.doc cmd # 查看所有的modules列表 salt '*' sys.li ...