• iOS网络: NSURLConnection进行异步请求


    介绍:
       iOS 的应用,一般是需要通过网络进行数据的交互的,这样你的应用就成为了联机的应用了。 

       iOS SDK 允许我们向网络发送请求,并且能够很方便的通过 NSURLConnection 这个类 来获取和发送数据,我们可以通过 NSJSONSerialization 对 JSON 进行序列化和反序列化。 XML 的解析则使用 NSXMLParser 类。可以通过 Twitter 框架进行 Twitter 进行连接。 

     

    一  通过NSURLConnection进行异步下载

    1.
    NSURLConnection 提供了两种方式来实现连接,一种是同步的另一种是异步的,异步 的连接将会创建一个新的线程,这个线程将会来负责下载的动作。而对于同步连接,在下载 连接和处理通讯时,则会阻塞当前调用线程。 
     
    许多开发者都会认为同步的连接将会堵塞主线程,其实这种观点是错误的。一个同步的连接是会阻塞调用它的线程。如果你在主线程中创建一个同步连接,没错,主线程会阻塞。 但是如果你并不是从主线程开启的一个同步的连接,它将会类似异步的连接一样。因此这种情况并不会堵塞你的主线程。事实上,同步和异步的主要区别就是运行 runtime 为会异步连接创建一个线程,而同步连接则不会。 
     
    2.
    为了能够创建一个异步的请求连接,我们需要做如下的操作。
    1. 创建一个 NSSring 类型的 URL 连接字符串。
    2. 把 NSString 类型转化成 NSURL 类型。
    3. 把我们的URL对象赋值到 NSURLRequest 对象中,如果是多个连接请求,请使用 NSMutableURLRequest.
    4. 创建一个 NSURLConnection 的连接实例,然后把我们定义好的 URL 请求赋值过去。 
      我们可以通过 NSURLConnection 的 sendAsynchronousRequest:queue:completionHandler 这个方法创建一个异步的 URL 连接对象。这个方法的参数如下: 
    sendAsynchronousRequest
       异步请求
    Queue   
      一个操作队列,我们可以很轻松的分配和初始化一个操作队列,然后可以根据我们需求添加 到这个参数中。

    completionHandler

      这是一个 block 对象,当我们异步的连接操作完成之后,无论我们的异步操作是否成功,都会执行这个 block,这个 block 对象都能够接收到如下三个参数:

        1).一个 NSURLResopne,这个对象封装了服务器返回给我们 response。

        2).NSData,可选的,这个是我们通过 URL 请求返回的数据。

        3).NSError 类型的对象,如果请求中有错误发生。 

     注意:

    sendAsynchronousRequest:queue:completionHandler: 方法不会在主线程中调用。因此如果你想执行一个跟 UI 相关的任务,那么请回到主线程中。 

    例子:

    - (void)sendAsynNetWork{
        NSString *urlString = @"http://www.apple.com";
        NSURL *url = [NSURL URLWithString:urlString];
        NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
        NSOperationQueue *queue = [[NSOperationQueue alloc]init];
        //发送异步请求
        [NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            if ([data length] > 0 && connectionError == nil) {
                NSString *html = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
                NSLog(@"HTML = %@",html);
                //保存从网络上下载的数据到你的硬盘中
                //1.获取存储路径
                NSString *documentsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
                //将文件名添加到存储路径上,形成文件路径
                NSString *filePath = [documentsDir stringByAppendingPathComponent:@"apple.html"];
                //将数据写入文件 存到硬盘
                [data writeToFile:filePath atomically:YES];
                NSLog(@"Successfully saved the file to %@",filePath);
            }
            else if ([data length] == 0 && connectionError == nil){
                NSLog(@"Nothing was downloaded");
            }
            else if (connectionError != nil){
                NSLog(@"connectionError happened = %@",connectionError);
            }
        }];
    }
    在 iOS SDK 早期的版本中,URL 连接使用的是 delegation 模型,不过,现在全部都使用 block 了,你不用在考虑实现 delegate 方法。 

    二. 处理异步连接中的超时

    创建一个异步的请求的时候,你想设置一个响应超时的值,来完善你的应用程序 

    讨论:

    当初始化 NSURLRequest 这个对象,并且把这个对象传递给 URL 连接对象的时候,你可以使用 requestWithURL:cachePolicy:timeoutInterval:这个类方法,将超时的值传递给 timeoutInterval 参数。 

    这里详细看第二个参数 cachePolicy:  参数值在 NSURLRequestCachePolicy(缓存策略) 枚举中选择:

    typedef NS_ENUM(NSUInteger, NSURLRequestCachePolicy)

    {

    1> NSURLRequestUseProtocolCachePolicy = 0, 默认的缓存策略, 如果缓存不存在,直接从服务端获取。如果缓存存在,会根据response中的Cache-Control字段判断下一步操作,如: Cache-Control字段为must-revalidata, 则询问服务端该数据是否有更新,无更新的话直接返回给用户缓存数据,若已更新,则请求服务端.
     
    2> NSURLRequestReloadIgnoringLocalCacheData = 1, 忽略本地缓存数据,直接请求服务端.
     
    3> NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, 忽略本地缓存,代理服务器以及其他中介,直接请求源服务端.
     
    4> NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData
     
    5> NSURLRequestReturnCacheDataElseLoad = 2, 有缓存就使用,不管其有效性(即忽略Cache-Control字段), 无则请求服务端.
     
    6> NSURLRequestReturnCacheDataDontLoad = 3, 死活加载本地缓存. 没有就失败. (确定当前无网络时使用)
     
    7> NSURLRequestReloadRevalidatingCacheData = 5, 缓存数据必须得得到服务端确认有效才使用(貌似是NSURLRequestUseProtocolCachePolicy中的一种情况)
     
    };
    Tips: URL Loading System默认只支持如下5中协议: 其中只有http://和https://才有缓存策略.
    (1) http://
    (2) https://
    (3) ftp://
    (4) file://
    (5) data://
     //设置更详细的request  第二个参数缓存策略 第三个参数最大等待时间
        NSURLRequest *urlrequest1 = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:15.0f];
     
     
     
     
  • 相关阅读:
    Vue-router2.0学习笔记(转)
    vue-cli 搭建项目
    打开一个vue项目
    Webpack,Browserify和Gulp三者之间到底是怎样的关系
    读取ByteBuffer有效的数据
    node-sass 安装失败的解决措施[转]
    SpringCloud2.0
    Docker
    分布式文件系统之FastDFS
    SVN的使用
  • 原文地址:https://www.cnblogs.com/safiri/p/4089034.html
Copyright © 2020-2023  润新知