iOS应用与HTTP服务器进行HTTP通信时会用到的API

在使用URL加载系统时,有3个主要的方法啊可以执行HTTP请求和接受响应:

同步 --启动线程的代码会阻塞,直到整个响应加载完毕并返回到调用方法为止,该技术容易实现,不过局限性也大。

队列式异步--起始代码创建一个请求,并将其放到一个队列中以在后台线程中执行。该技术的实现稍微有些难度,不过却消除了纯同步式技术的诸多限制。

异步--起始代码开启一个请求,该请求运行在起始线程中,不过在请求处理时会调用委托方法。该技术的实现最为复杂,不过在处理响应时却提供了最大的灵活性。


每个请求都有自己的方式和最佳实践,但这三种请求都由相同的4个对象构成。这三种请求会共用4类对象:NSURL, NSURLRequest, NSURLConnectionNSURLResponse.

NSURL

可以通过NSURL对象轻松管理URL值并访问URL指向的内容。NUSRL可以指向文件资源,也可以指向网络资源,同时在这两类资源类型的使用上没有任何区别。下面代码展示了如何从URL加载数据:

NSURL *url = [NSURL urlWithString:mysteryString];
NSData *data = [NSData dataWithContentsOfURL:url];

   mysteryString的值可以引用文件或网络资源,而代码的行为是一样的。主要的差别在于加载mysteryString所引用资源的时间上。如果URL引用的是网络资源,就会在后台线程中执行代码,这样在数据加载时用户界面就不会暂停下来。

   创建NSURL对象最常见的方式是使用类方法 URLWithString:进行实例化。该方法会创建一个NSURL对象,并使用提供的NSString对象的内容对其进行初始化:

 

 NSURL *url = [NSURL URLWithString:@"http://www.Google.com/path1"];

    NSURL对象提供了很多访问器方法来读取URL各个部分的值。每个访问器都可以只读访问URL的某一部分。scheme访问器会返回一个包含该URL所用协议的NSString对象。如果目标URL没有指定某个特定部分,那么返回值就为nil,考虑之前创建的url对象,下面代码会打印出 Port is nil.

    

if (url.port == nil){
    NSLog(@"Port is nil");
} else {
    NSLog(@"Port is not nil");
}

       如果URL包含查询字符串,那么query访问器方法就会包含所有需要查询参数的值。根据RFC 3986的要求,在创建NSURL对象前,URL字符串的内容需要以百分号编码。比如,如果执行下述代码片段,那么查询参数的值就为q=iOS+Networking

NSURL *url = [NSURL URLWithString:@"http://google.com?q=iOS+Networking"];

      NSURL对象是不可变的,这意味着无法先构建空的NSURL对象,然后通过调用对象的赋值方法(有时也叫setter)方法来装配其属性。对象要么(1)通过NSString对象,要么(2)通过另一个NSURL对象实例化.如果用于实例化NSURL对象的字符串是不合法的,那么创建方法就会返回nil。在使用URL对象进行网络请求前,应该验证URL对象是合法的。

 NSURLRequest

      创建好NSURL对象后,接下来就需要完成执行HTTP请求所需的下一步了:创建NSURLRequest对象。NSURLRequest对象包含了加载URL内容所需的信息,并且独立于URL中指定的协议。iOS中的URL加载系统支持HTTP,HTTPS,FTP,FILE URL内容的加载。URL加载系统提供了一种扩展方式以处理新的协议,方式是创建NSURLProtocol自雷,然后将返回结果提供给URL加载系统。
      创建NSURLRequest对象最简单的方式是通过类方法和提供的NSURL对象。下述代码片段展现了使用默认值来创建请求对象的过程   

NSURL *url = [NSURL URLWithString:@"https://gdata.youtube.com/feeds/api/standardfeeds/top_rated"];
if (url == nil) {
    NSLog(@"Invalid URL");        //验证URL是否正确
    return;
}
NSURLRequest *request = [NSURLRequest requestWithURL:url];
if (request == nil) {
    NSLog(@"Invalid request");
    return;
}

      默认值表示请求使用URL协议指定的请求缓存规则,请求有着标准的请求超时。如果URL是HTTP或HTTPS,那么请求方法将是GET。并且使用操作系统提供的默认头。
下列示例展示了如何使用自定义的缓存和超时值来创建NSURLRequest对象。构建URL加载系统的代码忽略了所有缓存,如果完成请求连接的时间超过20s,将会发生错误.


NSURLRequest对象提供了几个访问器方法来获取请求的属性,由于NSURLRequest类是不可变的,因此无法更改这些属性(readonly)。除了URL、缓存策略和超时值之外,如果要修改其他属性,那么请用NSMutableURLRequest类。
NSMutableURLRequest是NSURLRequest的子类,提供了赋值方法以修改请求的属性。下述代码片段展示了使用一小段消息体来创建一个简单的POST请求,它包含了以UTF8编码的一个NSString对象的字节。URL加载系统会自动装配请求的Content-Length头:

    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req setHTTPMethod:@"POST"];
[req setHTTPBody:[@"Post body" dataUsingEncoding:NSUTF8StringEncoding]];

有两种方式可以向NSURLRequest提供HTTP体:在内存中(就像之前的示例一样)或是通过NSInputStream。代码可以通过输入流提供请求体而无需将整个体加载到内存中。如果发送诸如照片或视频等大容量内容,那么使用输入流是最佳选择。下述代码片段展示了如何通过输入流创建POST方法,需要事先将NSString srcFilePath设定为应用包或是沙盒中的文件路径

    NSArray *srcArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *srcFilePath = srcArray[0];
srcFilePath = [srcFilePath stringByAppendingString:@"/filePath"];
NSInputStream *inStream = [NSInputStream inputStreamWithFileAtPath:srcFilePath];
[req setHTTPBodyStream:inStream];
[req setHTTPMethod:@"POST"];

由于NSURLRequest对象包含HTTP与非HTTP请求的属性,因此访问非 HTTP URL的代码需要将特定于HTTP的属性的值设为nil.

NSURLConnection

NSURLConnection对象是URL加载系统活动的中心,但提供的接口却不多,只提供了用于初始化、开启与取消连接的方法。。
回到上面提到的用于执行HTTP请求和获取响应的主要方法上来,NSURLConnection类通过3种不同的操作模式发挥作用:同步,异步,队列式异步。同步模式是最易于使用的,不过却有很多限制,这使得它不太适合更加高级的交互。异步模式提供了很大的灵活性,不过其代价就是增加了代码的复杂性。队列式异步模式提供了异步模式的后台操作,同时又保持了同步模式的简单性。
在异步模式下操作时,NSURLConnection对象会调用委托对象来指引连接流、处理到来的数据、处理认证并对错误做出响应。

NSURLResponse

NSURLReponse对象会再URL加载请求完毕后返回。响应对象的内容根据请求的类型及成功与否会有较大变化。如下列表介绍了从请求返回的各种对象。还有两个对象也可能来自于URL加载请求:NSError对象和NSData对象。如果请求有问题或者客户端无法连接到服务器,就会产生NSError对象。如果有响应返回,那么生成的NSData对象就会包含响应体。如果生成了NSError对象,就不会再生成NSURLResponse与NSData 对象。

  • MIMEType--结果数据的MIME类型。该值来自于服务器,如果客户端框架认为服务器有错,那么可以修改,如果服务器没有提供,还可以由客户端框架提供。
  • expectedContentLength--该值可能由请求返回,也可能不返回,返回值可能与返回内容的实际大小不同。如果返回内容的大小未知,那么该值将等于NSURLResponseUnknownLength
  • suggestedFilename--要么是服务器提供的内容文件名,要么来自于URL和MIME
    URL--返回内容的URL。由于重定向和标准化等原因,该URL可能与提供的URL不同。
  • textEncodingName--最初的数据源所用的文本编码名。如果响应中没有使用文本编码,那么该值将会是nil.
    URL加载系统提供了一个名为NSHTTPURLResponse的NSURLResponse子类,它包含特定于HTTP请求的属性。该类对于确定HTTP请求的结果是必需的。它有如下参数:

  • 响应头--该属性返回响应头值得NSDictionary对象。字典的键是头的名字,每个键的值是头的值。HTTP规范孕育一个请求有多个同名的头。NSHTTPURLResponse通过返回一个包含所有头值的NSString对象(头值之间用逗号分隔)来处理这一点。

  • HTTP状态码--来自于响应状态行的整数状态码。NSHTTPURLResponse类有一个类方法可以针对任意状态返回本地化的字符串说明。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值