zoukankan      html  css  js  c++  java
  • iOS 开发 中级:HTTP请求 GET POST 网络编程实现

    转自:http://blog.csdn.net/songrotek/article/details/8830372

    在开发网络相关的应用,比如微博应用时,就必然需要使用到HTTP请求来发送或者接收数据。最主要的就是使用GET方法或者POST方法。本文将详细介绍HTTP请求在iOS开发中的编程实现。
    1、对于HTTP请求的基本介绍
    这里不对原理做过多的介绍,大家可以Google之。对于完全不了解的童鞋,这里作个基本的说明。举新浪开放平台为例,我们要从手机发布一条新的状态,需 要通过网络向新浪微博的服务器发送请求,这个请求中包含了我们要发送的状态信息。请求的URL必须是新浪开放平台指定的才行。比如这个发送状态,URL是https://api.weibo.com/2/statuses/update.json。大家可以自己到开放平台查看,然后使用的HTTP请求方式是POST。然后要附带一些请求参数。HTTP请求有GET,POST,DELETE等等方式,不同的方式它的URL request格式不同,对于大多数使用情况,使用GET和POST就行。然后如果发送请求成功的话,就可以从服务器接受到相关的信息。
    GET是比较简单的请求方式,在URL中直接就包含了要发送的所有参数。还是以新浪开放平台的请求为例。我们要获取获 取某个用户最新发表的微博列表。那么这个基本的URL是https://api.weibo.com/2/statuses /user_timeline.json ,然后由于这个请求主要是接收数据,要附带的请求参数最基本的就两个,一个是access_token,一个uid就是用户的编号。
    那么一个基本的GET请求的URL就是
    https://api.weibo.com/2/statuses/user_timeline.json?access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxx&uid=xxxxxxxxxxxxxxx
    那么在iOS开发中,确定了URL,然后就是建立URLRequest,NSURLConnection去实现请求。当然,在实际中,GET方法也有它相关的报文格式,如下:
    GET /api.weibo.com/2/statuses/user_timeline.json?access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxx&uid=xxxxxxxxxxxxxxx HTTP/1.1
    Host: api.weibo.com
    HTTP/1.1 200 OK
    Content-Type: text/xml; charset=utf-8Content-Length: length 
    这里的很多参数都是默认,在Xcode中创建NSURLConnection的时候会自动加上。
    下面说一下 POST。POST可以这样理解主要用于向服务器上传数据,简单一点的是上传文字,复杂一点的是上传图片声音等等。那么对于这种需求显然如果使用GET的 话,那么这URL未免会太长。因此有POST方式的存在,可以在基本的URL的情况下,再附加一个数据包,包含要上传的数据,然后和URL一起发送给服务 器。
    POST方法有两种格式,一种是基本的格式,一般用于发送文字信息。
    Post请求基本格式如下:
    POST /login.asp HTTP/1.1
    Host: www.example.com
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 35
    username=wantsoft&password=password   //post的数据
    另一种是multipart/form-data,格式如下
    POST /upload_file/UploadFile HTTP/1.1 
    Accept: text/plain, */* 
    Accept-Language: zh-cn 
    Host: www.example.com 
    Content-Type:multipart/form-data;boundary=---------------------------7d33a816d302b6 
    User-Agent: Mozilla/4.0 (compatible; OpenOffice.org) 
    Content-Length: 424 
    Connection: Keep-Alive -----------------------------7d33a816d302b6 
    Content-Disposition:form-data; 
    name="userfile"; 
    filename="userfile"
    Content-Type: application/octet-stream abbXXXccc 
    -----------------------------7d33a816d302b6 
    Content-Disposition: form-data; 
    name="text1" foo 
    -----------------------------7d33a816d302b6 
    Content-Disposition: form-data; 
    name="password1" bar 
    -----------------------------7d33a816d302b6-- 
    看起来比较复杂,其实就是把请求数据通过分界线也就是Boundary分开,至于开头的一些内容,很多都是默认,无需考虑。
    2、Xcode编程实现
    2.1 HTTP请求的基本方法
    STEP 1: 创建URL
    一般我们用于URL的字符串。通过字符串创建URL
     NSString URLString;
    NSURL *URL = [NSURLURLWithString:[URLStringstringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    上面附加的stringByAddingPercentEscapesUsingEncoding:是为了保证URL字符串有效。
    STEP 2:创建URLRequest
    NSMutableURLRequest *URLRequest = [[NSMutableURLRequestalloc]initWithURL:finalURLcachePolicy:NSURLRequestReloadIgnoringLocalCacheDatatimeoutInterval:SR_TIME_OUT_INTERVAL];
    //如果是GET
        [URLRequest setHTTPMethod:@"GET"];
    //如果是POST
    [URLRequest setHTTPBody:[HTTPBodyStringdataUsingEncoding:NSUTF8StringEncoding]];
    [URLRequestsetHTTPMethod:@"POST"];
    STEP 3:通过NSURLConnection实现请求
    一般有两种方式,如果不需要知道请求的进度,比如文字上传,那么用简单的异步请求。如下:
    NSOperationQueue *queue = [[NSOperationQueuealloc]init];
    [NSURLConnectionsendAsynchronousRequest:self.URLRequestqueue:queuecompletionHandler:^(NSURLResponse *response,NSData *data,NSError *error){...};
    如果要知道请求的进度,比如图片发送的情况。那么就应该创建一个NSURLConnection的实例,并设置其delegate,通过其delegate方法来获取请求的实时状态,具体使用方法详见开发文档。
    2.2 HTTP GET方法的实现
    主要讲如何创建NSURLRequest
    这里我直接将我写的方法放下面:
    - (NSURLRequest *)HTTPGETRequestForURL:(NSURL *)url parameters:(NSDictionary *)parameters
    {
       NSString *URLFellowString = [@"?"stringByAppendingString:[selfHTTPBodyWithParameters:parameters]];
        
        NSString *finalURLString = [[url.absoluteStringstringByAppendingString:URLFellowString]stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        
       NSURL *finalURL = [NSURLURLWithString:finalURLString];
        
        NSMutableURLRequest *URLRequest = [[NSMutableURLRequestalloc]initWithURL:finalURLcachePolicy:NSURLRequestReloadIgnoringLocalCacheDatatimeoutInterval:TIME_OUT_INTERVAL];
        [URLRequestsetHTTPMethod:@"GET"];
        
       return URLRequest;
        
    }
    - (NSString *)HTTPBodyWithParameters:(NSDictionary *)parameters
    {
       NSMutableArray *parametersArray = [[NSMutableArrayalloc]init];
        
       for (NSString *keyin [parametersallKeys]) {
           id value = [parameters objectForKey:key];
           if ([value isKindOfClass:[NSStringclass]]) {
                [parametersArrayaddObject:[NSStringstringWithFormat:@"%@=%@",key,value]];
            }
            
        }
        
       return [parametersArray componentsJoinedByString:@"&"];
    }
    基本上就是通过方法把请求参数与URL连接起来,然后创建NSURLRequest
    2.3 HTTP POST 基本方法的实现
    - (NSURLRequest *)HTTPPOSTNormalRequestForURL:(NSURL *)url parameters:(NSDictionary *)parameters
    {
         NSMutableURLRequest *URLRequest = [[NSMutableURLRequestalloc]initWithURL:urlcachePolicy:NSURLRequestReloadIgnoringLocalCacheDatatimeoutInterval:TIME_OUT_INTERVAL];
       NSString *HTTPBodyString = [selfHTTPBodyWithParameters:parameters];
        [URLRequest setHTTPBody:[HTTPBodyStringdataUsingEncoding:NSUTF8StringEncoding]];
        [URLRequestsetHTTPMethod:@"POST"];
       return URLRequest;
        
    }
    这个和GET极其类似,只不过是把请求参数放在了HTTPBody中了。
    2.4 HTTP POST Multipart
    - (NSURLRequest *)HTTPPOSTMultipartRequestForURL:(NSURL *)url parameters:(NSDictionary *)parameters
    {
        NSMutableURLRequest *URLRequest = [[NSMutableURLRequestalloc]initWithURL:urlcachePolicy:NSURLRequestReloadIgnoringLocalCacheDatatimeoutInterval:TIME_OUT_INTERVAL];
        
        NSString *contentType = [NSStringstringWithFormat:@"multipart/form-data;boundary=%@",SR_POST_BOUNDARY];
    // 设置内容的类型 contentType,这完全是按照POST的格式来设置
        [URLRequestsetValue:contentType forHTTPHeaderField:@"Content-Type"];
        [URLRequestsetHTTPMethod:@"POST"];
        [URLRequest setHTTPBody:[selfHTTPPOSTMultipartBodyWithParameters:parameters]];
       return URLRequest;
    }
    // 用于创建Multipart Body,需要分割线,也是完全参考POST格式
    - (NSData *)HTTPPOSTMultipartBodyWithParameters:(NSDictionary *)parameters
    {
        NSMutableData *body = [NSMutableDatadata];
        
        // Add Body Prefix String
        [body appendData:[[NSStringstringWithFormat:@"--%@ ",SR_POST_BOUNDARY]dataUsingEncoding:NSUTF8StringEncoding]];
        
        // Add Main Body
       for (NSString *keyin [parametersallKeys]) {
           id value = [parameters objectForKey:key];
            
           if ([value isKindOfClass:[NSStringclass]]){
                [body appendData:[[NSStringstringWithFormat:@"Content-Disposition: form-data; name="%@" %@ ",key,value]dataUsingEncoding:NSUTF8StringEncoding]];
                [body appendData:[[NSStringstringWithFormat:@"--%@ ",SR_POST_BOUNDARY]dataUsingEncoding:NSUTF8StringEncoding]];
            }else {
                NSLog(@"please use addMultiPartData:withName:type:filename: Methods to implement");
            }
        }
       return body;
    }
    // 在最后要附加上请求参数中的图片等等大的数据!
    - (void)addMultiPartData:(NSData *)data
                    withName:(NSString *)name
                        type:(NSString *)type
                    filename:(NSString *)filename
    {
       NSMutableURLRequest *URLRequest = [self.URLRequestmutableCopy];
       NSMutableData *body = [URLRequest.HTTPBodymutableCopy];
        
        // Step 1
       NSString *disposition = [[NSStringalloc]init];
       if (!filename) {
            disposition =
            [NSStringstringWithFormat:@"Content-Disposition: form-data; name="%@"; filename="%@" ", name, filename];
        }else {
            disposition =
            [NSStringstringWithFormat:@"Content-Disposition: form-data; name="%@"; filename="%@" ", name, name];
        }
        [body appendData:[dispositiondataUsingEncoding:NSUTF8StringEncoding]];
        
        // Step 2
       NSString *contentType = [NSStringstringWithFormat:@"Content-Type: %@ ",type];
        [body appendData:[contentTypedataUsingEncoding:NSUTF8StringEncoding]];
        
        // Step 3
        [bodyappendData:data];
        
        // Step 4 Add suffix boundary
       NSString *boundary = [NSStringstringWithFormat:@" --%@-- ",SR_POST_BOUNDARY];
        [body appendData:[boundarydataUsingEncoding:NSUTF8StringEncoding]];
        
        // Step 5
        [URLRequestsetHTTPBody:body];
       self.URLRequest = URLRequest;
    }
    3、下面说一下接受数据
    一般我们要把NSData数据变成JSON数据,大都是情况下获得的JSON Object是NSDictionary或NSArray
    基本方法是
    id receivedData = [NSJSONSerializationJSONObjectWithData:dataoptions:NSJSONReadingMutableContainers |NSJSONReadingMutableLeaveserror:nil];
    然后就可以进行相关的处理了!

  • 相关阅读:
    hdu 4002 Find the maximum
    hdu 2837 坑题。
    hdu 3123
    zoj Treasure Hunt IV
    hdu 2053 Switch Game 水题一枚,鉴定完毕
    poj 1430 Binary Stirling Numbers
    hdu 3037 Saving Beans
    hdu 3944 dp?
    南阳oj 求N!的二进制表示最低位的1的位置(从右向左数)。
    fzu 2171 防守阵地 II
  • 原文地址:https://www.cnblogs.com/qc0815/p/3412316.html
Copyright © 2011-2022 走看看