zoukankan      html  css  js  c++  java
  • Objective-C Http常用API 同步请求与异步请求

    开发iOS应用要调用Http接口、获取Http资源,有一套比较成熟的框架ASIHTTPRequest。而我还是比较喜欢使用原始一点的 API,而它跟其他的面向对象语言有许多共通之处。本文分同步请求和异步请求这两种情况来讲解一下Http API的使用。直接上代码,注释即文档!

    同步请求:即发起Http请求、获取并处理返回值都在同一个线程中进行

    01.//创建URL对象
    02.NSString *urlStr = @"http://blog.csdn.net/rongxinhua";
    03.NSURL *url = [[NSURL alloc] initWithString:urlStr];
    04. 
    05.//创建HTTP请求
    06.//方法1(注:NSURLRequest只支持Get请求,NSMutableURLRequest可支持Get和Post请求)
    07.NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
    08.NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    09.//方法2,使用工厂方法创建
    10.NSURLRequest *request = [NSURLRequest requestWithURL:url];
    11.NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    12.//同时设置缓存策略和超时时间
    13.NSMutableURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15];
    14. 
    15.//设置Http头
    16.NSDictionary *headers = [request allHTTPHeaderFields];
    17.[headers setValue:@"iOS-Client-ABC" forKey:@"User-Agent"];
    18. 
    19.//设置请求方法
    20.[request setHTTPMethod:@"GET"];
    21.[request setHTTPMethod:@"POST"];
    22. 
    23.//设置要发送的正文内容(适用于Post请求)
    24.NSString *content = @"username=stanyung&pass<a href="http://www.it165.net/edu/ebg/" target="_blank" class="keylink">word</a>=123";
    25.NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
    26.[request setHTTPBody:data];
    27. 
    28.//同步执行Http请求,获取返回数据
    29.NSURLResponse *response;
    30.NSError *error;
    31.NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    32. 
    33.//返数据转成字符串
    34.NSString *html = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
    35. 
    36.//(如果有错误)错误描述
    37.NSString *errorDesc = [error localizedDescription];
    38. 
    39.//获取状态码和HTTP响应头信息
    40.NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
    41.NSInteger statusCode = [httpResponse statusCode];
    42.NSDictionary *responseHeaders = [httpResponse allHeaderFields];
    43.NSString *cookie = [responseHeaders valueForKey:@"Set-Cookie"];

    注:以上代码,不要Copy直接执行,只是列举Http常用方法的调用。

    异步请求:发起HTTP请求在一个线程中,返回结果处理在另一个线程中。相比同步请求,异步请求不需要等待返回结果,当前程序可以继续往下执行。在Objective-C中,异步请求也有两种实现方式:一种是注册回调代理,一种是使用回调代码块。

    a.注册回调代理的方式:

    1.[NSURLConnection connectionWithRequest:request delegate:self];

    需要实现NSURLConnectionDataDelegate协议:

    1.@interface HttpDownloadService : NSObject<NSURLConnectionDataDelegate> {  
    2.}

    实现相关的协议方法:

    01.NSMutableData *buff;    //暂存响应的数据
    02.bool finished = false//读完完整标记
    03. 
    04.//收到HTTP响应时调用
    05.-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    06.NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
    07.NSDictionary *headers = [httpResponse allHeaderFields];
    08.buff = [[NSMutableData alloc] init];
    09.}
    10. 
    11.//读取返回数据时调用(可能会执行多次此方法)
    12.-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    13.[buff appendData:data];
    14.}
    15. 
    16.//读完数据完成时调用
    17.-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
    18.NSString *html = [[NSString alloc] initWithData:buff encoding:NSUTF8StringEncoding];
    19.finished = true;
    20.}

    通常情况下,数据在网络中传输,会受到带宽等因素的影响,并不会一次情将所有数据返回,你可能分几次才能接受完整一个HTTP响应报文。因此, (void)connection:(NSURLConnection *)didReceiveData:(NSData *) 这个方法很可能会执行多次。

    上例代码中,使用了NSMutableData来暂存接收到的响应数据片段,每一段并接起来,直到读取完整。

    b.使用回调代码块的方式:

    1.[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:
    2.^(NSURLResponse *response, NSData *result, NSError *error){       //只会进入一次,方法内部已经实现了Buffer作用
    3.NSString *html = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
    4.}];

    跟NSURLConnectionDataDelegate的回调方法不同,这里的回调代码块只调用一次,它内部已经实现了Buffer的作用,等到数据接收完整后才进入此代码块。因此,你在代码块中获取到的result可以直接使用。

    备注1:本文的代码例子将使用ARC编码模式,故所新建的对象均没有显式调用release()方法回收。

    备注2:若你测试本例子代码新建的是Command Line Tool工程,在main函数中执行相关代码,上面两种异步执行的情况,你很可能你的程序没有执行到回调方法或回调代码块里面去,这是因为:在main函 数中,主线程没有等待阻塞,一下子执行完了,回调代码所在的子线程可能未执行完或者根本还没开始执行,就已经因为主线程的结束而结束了。解决这个问题,可 以在调用完异步方法后面,加以下代码:

    1.while (!finished) {
    2.[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    3.}

    而finished变量正是上面两个异步HTTP例子中定义是否执行完成的变量。

     
  • 相关阅读:
    loaded some nib but the view outlet was not set
    指标评比
    IOS DEVELOP FOR DUMMIES
    软件测试题二
    javascript select
    DOM节点类型详解
    mysql操作
    UVA 10055
    solutions for 'No Suitable Driver Found For Jdbc'
    解决git中文乱码问题
  • 原文地址:https://www.cnblogs.com/ITmgc/p/4471880.html
Copyright © 2011-2022 走看看