iOS 网络请求 笔记

有关网络请求的类(该图片来自:developer.apple.com)

一、url请求

网络请求的组成部分有服务器地址、请求参数,以及请求方式。在iOS中,一个网络请求用NSURLRequest(或者其子类NSURLMutableRequest)来表示。

NSURLRequest适合于get请求,NSURLMutableRequest可以是post请求。

get方式下,服务器地址和请求参数都可以明文包含在url中,可以直接使用这个url来创建NSURLRequest(或者NSURLMutableRequest)。

post方式下,服务器地址用NSURL来表示,请求参数可以封装到NSData中(也可以以文件或者流的形式保存)。由于需要将服务器地址和请求参数分开,所以需要用到NSURLMutableRequest类。用服务器地址的url创建NSURLMutableRequest对象,然后将封装了请求参数的NSData对象添加到这个NSURLMutableRequest对象中。示例如下:

NSURL *url=[NSURL URLWithString:@“http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx"];
NSData *data=[@"date=20151101&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213" dataUsingEncoding:NSUTF8StringEncoding];

然后将服务器地址与请求参数加入到NSURLMutableRequest对象中:

NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:60];
request.HTTPMethod[email protected]"post";//指明请求方式为post,默认为get
request.HTTPBody=data;

这样就准备好了一个网络请求,接下来就是如何去执行这个网络请求的问题。

二、执行url请求

执行url请求可以使用iOS原生API也可以使用第三方库。

执行url请求的两个原生方法:

(1)NSURLSession

(2)NSURLConnection

iOS 7.0 以后推荐使用NSURLSession,以前使用NSURLConnection。

NSURLSession、NSURLConnection都可以发送和接收以NSData或者文件的形式保存的数据.

实现url请求的第三方库有afNetworking、sdWebImage等。

1.两个原生方法的基本使用思路

(1)每个项目都有一个NSURLSession对象,可以通过[NSURLSession sharedSession]方法来获取它,然后就可以用它来新建请求任务。该任务调用resume方法后开始执行。请求任务有三种,上传、下载、数据。通过NSURLSession来执行url请求是异步的。

(2)NSURLConnection直接执行send方法(类方法)发送请求,可以选择同步也可以选择异步。异步发送请求接收数据的话可以使用block接收,也可以使用代理。注意如果使用代理来接收数据,数据会是断续接收的。通常使用block比较方便。

同步和异步的区别就是,同步就是执行完网络请求方法后,要等到网络请求得到响应并完成数据传输之后才返回,异步就是发送完请求之后马上返回。

2. NSURLSession详解

获取session可以通过初始化方法,也可以直接使用项目默认的session对象,通过sharedSession方法获取。初始化session对象需要指定代理,如果指定为nil,就是使用系统默认的代理。

(1)session的分类

session分为3种:

  • 默认的(default session):会将存储数据存到硬盘上。
  • 短暂的(ephemeral session):不会存储任何数据到硬盘上,只会占用内存,当session释放了,所有的数据也就没有了。
  • 后台的(background session):和默认的session的区别在于会用独立的过程来处理数据传输。

初始化session的时候需要指定一个NSURLSessionConfiguration对象,session的类型就由这个对象的类型来确定。

(2)任务task的分类

任务分为3种,数据、下载、上传:

  • data task数据任务:发送和接收NSData形式的数据
  • download task下载任务:解析文件形式的数据,支持app没有运行的时候在后台执行。
  • upload task上传任务:发送文件形式的数据,也支持后台执行。

(3)任务task和session的关系

  • 任务的初始化和任务的管理都由session来完成。
  • 每个session对象管理着它自己创建的任务。
  • 任务创建后需要执行resume方法,session才会处理它。
  • 任务处理的具体操作是由session的代理来完成的,也就是说具体的处理会写在代理方法中。

(4)利用session完成后台传输

需要注意的问题:

  • 只有后台类型的session才可以新建支持后台传输的任务(下载任务或上传任务)。而且后台上传只支持文件上传,如果上传的是NSData对象或者数据流,在app退出后就会断掉。
  • 后台任务只支持http和https协议,不支持自定义协议。
  • 如果后台传输的任务是在app已经进入了后台之后才初始化的,那么session的NSURLSessionConfiguration对象的discretionary属性值为true。
  • 由于网络错误导致的后台上传或后台下载任务失败,系统会自动重新尝试执行这些任务,所以不需要自己写代码来重新执行失败的后台任务。

后台任务与app的交互:

后台任务的特点就是运行在后台,当app不在运行的时候后台任务仍然可以运行。

上面说过,任务的处理是由session的代理方法来完成的,但是当app没有运行的时候,session已经被释放,这时候后台任务怎么和创建这个任务的session重新关联起来呢?

这个问题iOS系统已经有一套完整的机制去处理它。是这样的:当后台任务完成或者需要认证的时候,如果app没有在运行,系统就会唤醒app,并调用app delegate的(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler方法。这个方法就是特地写来处理后台任务的,下面所描述的内容都围绕这个方法来展开。

需要重写在这个方法,在这个方法中让后台任务和session重新关联起来。由于创建它的session已经释放,要找回它不可能,实际的做法是创建一个和它一样的session,然后让任务与这个session关联起来。具体就是用这个方法的参数identifier来新建一个NSURLSessionConfiguration对象,并且用这个NSURLSessionConfiguration对象新建一个session,这个session就可以当成是原来的session了。神奇的是,只要这样创建了session,正在运行的任务就会自动和它关联起来,至于是怎么做到了,不需要操心,系统已经解决了。

留意到这个方法有一个block类型的参数completionHandler,它的意义在于,一旦它被执行就表明后台任务处理完成,因此系统自唤醒app之后就会一直等待completionHandler的执行,以便让app重新停止运行。因此,要记得把completionHandler传给session的代理,并且在session的代理方法URLSessionDidFinishEventsForBackgroundURLSession:中调用它,这样就实现了在最后一个任务处理完毕以后让app再次进入后台。

在正在运行的任务已经和session重新取得联系之后就会调用其代理的相关方法,如果是后台任务完成,就会调用URLSession:downloadTask:didFinishDownloadingToURL:方法。如果是需要认证,就会调用URLSession:task:didReceiveChallenge:completionHandler:方法或者URLSession:didReceiveChallenge:completionHandler:方法。

官网例子:https://developer.apple.com/library/ios/samplecode/SimpleBackgroundTransfer/Introduction/Intro.html#//apple_ref/doc/uid/DTS40013416

(4)下载文件

与文件下载有关的协议方法:

  • URLSession:downloadTask:didFinishDownloadingToURL:

    文件下载完成后调用,可以获取下载好的文件的url

  • URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:

    下载过程中调用

  • URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:

    该方法在开始恢复一个失败的下载任务之后调用

  • URLSession:task:didCompleteWithError:

    下载任务完成或终止后调用,如果任务出错,可以获取到NSError对象

  • 终止下载任务

    可以调用NSURLSessionDownloadTask对象的方法:cancelByProducingResumeData:

  • 恢复下载任务

    可以调用sessiondownloadTaskWithResumeData:downloadTaskWithResumeData:completionHandler:

    这里的resumeData从协议方法URLSession:task:didCompleteWithError:中的NSError对象的userInfo字典中会有,对应key为NSURLSessionDownloadTaskResumeData

(5)重定向

相关协议方法:

- (void)URLSession:(NSURLSession *)session?              task:(NSURLSessionTask *)task?willPerformHTTPRedirection:(NSHTTPURLResponse *)response?        newRequest:(NSURLRequest *)request? completionHandler:(void (^)(NSURLRequest *))completionHandler

对于默认的session和暂时的session管理的url请求任务发生重定向时就会调用这个方法,而后台任务发生重定向会直接服从重定向。

在这个方法里面,可以获取到新的url请求,调用completionHandler(request);就会允许重定向。如果调用completionHandler(nil);就相当于拒绝重定向。当然也可以调用completionHandler(otherRequest);实现自定义重定向。

时间: 2024-10-13 15:53:16

iOS 网络请求 笔记的相关文章

ios网络请求3840错误的问题

ios网络请求3840错误的问题 by 伍雪颖 Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn't be completed. (Cocoa error 3840.)" (Unterminated string around character 11080.) UserInfo=0x171065d00 {NSDebugDescription=Unterminated string around charac

iOS网络请求框架:MKNetWorkKit的使用

MKNetWorkKit是由一个印度小伙子写的,是用于网络请求的库,支持ARC,我fork了一下,代码的网址这里给出. 本人fork作者代码地址(DoubleYi):https://github.com/DoubleYi/MKNetworkKit 作者源码地址(MugunthKumar):https://github.com/MugunthKumar/MKNetworkKit 作者关于类库介绍的地址(MugunthKumar):http://blog.mugunthkumar.com/produ

iOS网络编程笔记——Socket编程

一.什么是Socket通信: Socket是网络上的两个程序,通过一个双向的通信连接,实现数据的交换.这个双向连路的一端称为socket.socket通常用来实现客户方和服务方的连接.socket是TCP/IP协议的一个十分流行的编程接口.一个socket由一个IP地址和一个端口号唯一确定.TCP/IP协议的传输层又有两种协议:TCP(传输控制协议)和UDP(用户数据报协议).TCP是基于连接的,而UDP是无连接的:TCP对系统资源的要求较多,而UDP少:TCP保证数据的正确性而UDP可能丢包:

 iOS 网络请求缓存:NSURLCache详解

我读过一些开源项目的网络请求缓存的代码,基本上都是采用在本地存文件的方式进行缓存.如果你打算在你的项目中加入网络请求的缓存,可能你并不需要自己造一个轮子,了解一下 NSURLCache 就足够.本文为大家接收的就是ios开发中的NSURLCache相关使用,一起来看看吧. 缓存 首先, NSURLCache 提供的是内存以及磁盘的综合缓存机制.许多文章谈到,使用NSURLCache 之前需要在 AppDelegate 中缓存空间的设置: - (BOOL)application:(UIApplic

IOS 网络请求方式

iOS开发中的网络请求 今天来说说关于iOS开发过程中的网络请求. 关于网络请求的重要性我想不用多说了吧.对于移动客户端来说,网络的重要性不言而喻.常见的网络请求有同步GET, 同步POST, 异步GET, 异步POST.今天来看一下四种网络请求的实现方式. 一.同步GET 1 2 3 4 5 6 7 8 9 10 11 12 // 1.将网址初始化成一个OC字符串对象 NSString *urlStr = [NSString stringWithFormat:@"%@?query=%@®ion

iOS网络请求基础

这篇是关于网络请求的,结合公司的实际情况编写,如果有不同意见欢迎留言共同讨论. iOS在9.0之后彻底放弃了NSURLConnection,现在已经改用了NSURLSession进行网络请求.一般现在网络请求也都是使用AFNetworking.下面就把我自己关于afn和系统的api使用写下来. 一.使用NSURLSession 移动端的网络请求主要是get请求和post请求, get和post请求步骤差不多,只不过post对于信息的传送更安全,post请求会设置body而且会对body进行加密,

ios 网络请求总结加强对中文的处理 问题:URL不允许写中文 在GET请求中,相关代码段打断点以验证。

开发还是需要多多练习的 ,下面是一些常用的步骤: 一.简单说明 创建Get 请求 //    1.设置请求路径 NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text]; NSURL *url=[NSURL URLWithString:urlStr]; //

iOS 网络请求NSURLSession

iOS 7 和 Mac OS X 10.9 Mavericks 中一个显著的变化就是对 Foundation URL 加载系统的彻底重构. 现在已经有人在深入苹果的网络层基础架构的地方做研究了,所以我想是时候来分享一些对于我对于这些新的 API 的看法和心得了,新的 API 将如何影响我们编写程序,以及它们对于 API 设计理念的影响. NSURLConnection 作为 Core Foundation / CFNetwork 框架的 API 之上的一个抽象,在 2003 年,随着第一版的 S

IOS 网络请求

技术交流新QQ群:414971585 关于网络请求的重要性我想不用多说了吧.对于移动客户端来说,网络的重要性不言而喻.常见的网络请求有同步GET, 同步POST, 异步GET, 异步POST.今天来看一下四种网络请求的实现方式. 一.同步GET 1 2 3 4 5 6 7 8 9 10 11 12 // 1.将网址初始化成一个OC字符串对象 NSString *urlStr = [NSString stringWithFormat:@"%@?query=%@®ion=%@&output=