iOS HTTP请求与解析

1 HTTP两种请求方案

1),苹果原生

NSURLConnect:经典简单

NSURLSession:iOS7新出,功能较强大

CFNetwork:NSURL*的底层,纯C语言

2),第三方框架(建议使用,提高效率)

ASIHttpRequest:功能十分强大,但停止更新

AFNetworking:主流,简单易用,更新十分快

MKNetworkKit:简单,但少用

2 HTTP的通信过程

1).请求

1> 请求行 : 请求方法、请求路径、HTTP协议的版本

GET /MJServer/resources/images/1.jpg HTTP/1.1

2> 请求头 : 客户端的一些描述信息

* User-Agent : 客户端的环境(软件环境)

3> 请求体 : POST请求才有这个东西

* 请求参数,发给服务器的数据

2).响应

1> 状态行(响应行): HTTP协议的版本、响应状态码、响应状态描述

HTTP/1.1 200 OK

2> 响应头:服务器的一些描述信息

* Content-Type : 服务器返回给客户端的内容类型

* Content-Length : 服务器返回给客户端的内容的长度(比如文件的大小)

3> 实体内容(响应体)

* 服务器返回给客户端具体的数据,比如文件数据

3 移动端HTTP请求分析数据的步骤

1.拼接"请求URL" + "?" + "请求参数"

* 请求参数的格式:参数名=参数值
* 多个请求参数之间用&隔开:参数名1=参数值1&参数名2=参数值2
* 比如:http://localhost:8080/MJServer/login?username=123&pwd=456

2.发送请求

3.解析服务器返回的数据

3.1 iOS中发送HTTP请求方式

1).GET

1> 特点

* 所有请求参数都拼接在url后面

2> 缺点

* 在url中暴露了所有的请求数据,不太安全

* url的长度有限制,不能发送太多的参数

3> 使用场合

* 如果仅仅是向服务器索要数据,一般用GET请求

* 默认就是GET请求

4> 如何发送一个GET请求

// 1.URL
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
// 2.请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 3.发送请求(子线程发送)
[NSURLConnection sendAsynchronousRequest:request 
                                    queue:[NSOperationQueue mainQueue] 
                         ompletionHandler:^(NSURLResponse *response, 
                                                        NSData *data, 
                                                        NSError *connectionError) {
}];
    //发送一个同步请求(在主线程发送请求)
    NSData *data = [NSURLConnection sendSynchronousRequest:request 
                                                    returningResponse:nil error:nil];

2).POST

1> 特点

* 把所有请求参数放在请求体(HTTPBody)中

* 理论上讲,发给服务器的数据的大小是没有限制

2> 使用场合

* 除开向服务器索要数据以外的请求,都可以用POST请求

* 如果发给服务器的数据是一些隐私、敏感的数据,绝对要用POST请求

3> 如何发送一个POST请求

// 1.创建一个URL : 请求路径
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/login"];
// 2.创建一个请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 设置请求方法
request.HTTPMethod = @"POST";
// 设置请求体 : 请求参数
NSString *param = [NSString stringWithFormat:@"username=%@&pwd=%@", username, pwd];
// NSString --> NSData
request.HTTPBody = [param dataUsingEncoding:NSUTF8StringEncoding];
// 3.发送请求(子线程发送)
[NSURLConnection sendAsynchronousRequest:request 
                                    queue:[NSOperationQueue mainQueue] 
                         ompletionHandler:^(NSURLResponse *response, 
                                                        NSData *data, 
                                                        NSError *connectionError) {
}];
    //发送一个同步请求(在主线程发送请求)
    NSData *data = [NSURLConnection sendSynchronousRequest:request 
                                                    returningResponse:nil error:nil];

3.2 解析服务器返回的数据

1)JSON解析

1>特点

*JSON解析规律

* { } --> NSDictionary @{ }
* [ ] --> NSArray @[ ]
* " " --> NSString @" "
* 10 --> NSNumber @10

*数据量少,服务器常用返回的数据

  // 3.发送请求(子线程发送)
  * request : 需要发送的请求
  * queue : 一般用主队列,存放handler这个任务
  * handler : 当请求完毕后,会自动调用这个block
[NSURLConnection sendAsynchronousRequest:request 
                                    queue:[NSOperationQueue mainQueue] 
                         ompletionHandler:^(NSURLResponse *response, 
                                                        NSData *data, 
                                                        NSError *connectionError) {
   // 解析服务器返回的JSON数据
    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data 
                                           options:NSJSONReadingMutableLeaves 
                                           error:nil];
    NSString *error = dict[@"error"];
    if (error) return; 
     else {
        NSString *success = dict[@"success"];
    }
                                                        
}];

2)XML解析

1.语法

1> 文档声明

<?xml version="1.0" encoding="UTF-8" ?>

2> 元素

* videos和video是元素(节点)

* video元素是videos元素的子元素

3> 属性

<videos>
    <video name="小黄人 第01部" length="10"/>
    <video name="小黄人 第01部" length="10"/>
</videos>

* name和length叫做元素的属性

2.解析

1> SAX解析

*逐个元素往下解析,适合大文件

* NSXMLParser

[NSURLConnection sendAsynchronousRequest:request 
                                    queue:[NSOperationQueue mainQueue] 
                         ompletionHandler:^(NSURLResponse *response, 
                                                        NSData *data, 
                                                        NSError *connectionError) {
        if (connectionError || data == nil) {
            [MBProgressHUD showError:@"网络繁忙,请稍后再试!"];
            return;
        }
        // 解析XML数据
        // 1.创建XML解析器 -- SAX -- 逐个元素往下解析
        NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
        // 2.设置代理 重要!
        parser.delegate = self;
        // 3.开始解析(同步执行)
        [parser parse];
        // 4.刷新表格
        [self.tableView reloadData];
    }];

/**
 *  解析到一个元素的开始就会调用
 *  @param elementName   元素名称
 *  @param attributeDict 属性字典
 */
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
                                        namespaceURI:(NSString *)namespaceURI 
                                       qualifiedName:(NSString *)qName 
                                          attributes:(NSDictionary *)attributeDict
{
    if ([@"videos" isEqualToString:elementName]) return;
    
    HMVideo *video = [HMVideo videoWithDict:attributeDict];
    [self.videos addObject:video];
}

// 解析到文档的开头时会调用
- (void)parserDidStartDocument:(NSXMLParser *)parser

/* 解析到一个元素的结束就会调用
 *   @param elementName   元素名称
 */  
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
                                      namespaceURI:(NSString *)namespaceURI 
                                     qualifiedName:(NSString *)qName

// 解析到文档的结尾时会调用(解析结束)
- (void)parserDidEndDocument:(NSXMLParser *)parser
2> DOM解析

*一口气将整个XML文档加载进内存,适合小文件,使用最简单

* GDataXML的使用步骤:

    1>导入这个GDataXML文件

    2>添加libxml2.dylib这个动态库

    3>在Bulid Settings的Header Search Paths 添加路径  /usr/include/libxml2

    4>在Bulid Phases的Compile Sources 找到CDataXMLNode 添加 -fno-objc-arc,通知编译器这是非arc

// 3.发送请求
[NSURLConnection sendAsynchronousRequest:request 
                                    queue:[NSOperationQueue mainQueue] 
                         ompletionHandler:^(NSURLResponse *response, 
                                                        NSData *data, 
                                                        NSError *connectionError) {
        if (connectionError || data == nil) {
            [MBProgressHUD showError:@"网络繁忙,请稍后再试!"];
            return;
        }
        // 解析XML数据
        // 加载整个XML数据
        GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data 
                                                        options:0 error:nil];
       // 获得文档的根元素 -- videos元素
        GDataXMLElement *root = doc.rootElement;
      // 获得根元素里面的所有video元素
        NSArray *elements = [root elementsForName:@"video"];
      // 遍历所有的video元素
        for (GDataXMLElement *videoElement in elements) {
            HMVideo *video = [[HMVideo alloc] init];
           / 取出元素的属性
           video.id = [videoElement attributeForName:@"id"].stringValue.intValue;
           video.name = [videoElement attributeForName:@"name"].stringValue;
           video.image = [videoElement attributeForName:@"image"].stringValue;
           video.url = [videoElement attributeForName:@"url"].stringValue;
             // 添加到数组中
           [self.videos addObject:video];
        }
        // 刷新表格
        [self.tableView reloadData];
    }];

4 数据安全

4.1.网络数据加密

1> 加密对象:隐私数据,比如密码、银行信息

2> 加密方案

* 提交隐私数据,必须用POST请求

* 使用加密算法对隐私数据进行加密,比如MD5

3> 加密增强:为了加大破解的难度

* 对明文进行2次MD5 : MD5(MD5($pass))

* 先对明文撒盐,再进行MD5 : MD5($pass.$salt) 撒盐是添加一些干扰数据

* 先MD5加密,再打乱暗文顺序

4.2.本地存储加密

1> 加密对象:重要的数据,比如游戏数据

4.3.代码安全问题

1> 现在已经有工具和技术能反编译出源代码:逆向工程

* 反编译出来的都是纯C语言的,可读性不高

* 最起码能知道源代码里面用的是哪些框架

5 监测网络状态

5.1.主动监测监测网络状态

// 是否WIFI  类方法
+ (BOOL)isEnableWIFI {
    return ([[Reachability reachabilityForLocalWiFi] 
                    currentReachabilityStatus] != NotReachable);
}
// 是否3G
+ (BOOL)isEnable3G {
    return ([[Reachability reachabilityForInternetConnection] 
                    currentReachabilityStatus] != NotReachable);
}

5.2.使用通知监控网络状态

1>使用苹果官方提供的 Reachability类

1> 监听通知
[[NSNotificationCenter defaultCenter] addObserver:self 
                            selector:@selector(networkStateChange) 
                            name:kReachabilityChangedNotification object:nil];
2> 开始监听网络状态
// 获得Reachability对象
self.reachability = [Reachability reachabilityForInternetConnection];
// 开始监控网络
[self.reachability startNotifier];

5.3.移除监听

- (void)delloc
{
    [self.reachability stopNotifier];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

6 iOS7:NSURLSession

1> NSURLSessionDataTask
* 用途:用于非文件下载的GET\POST请求
NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request];
NSURLSessionDataTask *task = [self.session dataTaskWithURL:url];
NSURLSessionDataTask *task = [self.session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
       }];

2> NSURLSessionDownloadTask
* 用途:用于文件下载(小文件、大文件)
NSURLSessionDownloadTask *task = [self.session downloadTaskWithRequest:request];
NSURLSessionDownloadTask *task = [self.session downloadTaskWithURL:url];
NSURLSessionDownloadTask *task = [self.session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
    
}];

7 下载

6.1.小文件下载

* 直接使用NSData
* NSURLConnection发送异步请求的方法
1.block形式 - 除开大文件下载以外的操作,都可以用这种形式
//使用了block就不需要使用代理方法
[NSURLConnection sendAsynchronousRequest:<#(NSURLRequest *)#> queue:<#(NSOperationQueue *)#> completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
 }];

6.2.大文件下载(断点下载)

1>利用NSURLConnection和它的代理方法
@property (nonatomic, strong) NSFileHandle *writeHandle;
@property (nonatomic, assign) long long totalLength;
@property (nonatomic, assign) long long currentLength;
@property (nonatomic, strong) NSURLConnection *conn;

1> 发送一个请求
// 1.URL
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/resources/videos.zip"];
// 2.请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 3.下载(创建完conn对象后,会自动发起一个异步请求)
//要遵守NSURLConnectionDataDelegate协议
[NSURLConnection connectionWithRequest:request delegate:self];

2>#pragma mark - NSURLConnectionDataDelegate代理方法 
在代理方法中处理服务器返回的数据
/**
 在接收到服务器的响应时:
 1.创建一个空的文件
 2.用一个句柄对象关联这个空的文件,目的是:方便后面用句柄对象往文件后面写数据
 */
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    // 文件路径
    NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString *filepath = [caches stringByAppendingPathComponent:@"videos.zip"];
    
    // 创建一个空的文件 到 沙盒中
    NSFileManager *mgr = [NSFileManager defaultManager];
    [mgr createFileAtPath:filepath contents:nil attributes:nil];
    
    // 创建一个用来写数据的文件句柄
    self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:filepath];
}

/**
 在接收到服务器返回的文件数据时,利用句柄对象往文件的最后面追加数据
 */
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // 移动到文件的最后面
    [self.writeHandle seekToEndOfFile];
    
    // 将数据写入沙盒
    [self.writeHandle writeData:data];
}

/**
 在所有数据接收完毕时,关闭句柄对象
 */
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // 关闭文件
    [self.writeHandle closeFile];
    self.writeHandle = nil;
}

3,断点下载
- (IBAction)download:(UIButton *)sender {
    // 状态取反
    sender.selected = !sender.isSelected;
    if (sender.selected) { // 继续(开始)下载
        // 1.URL
        NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/resources/videos.zip"];
       // 2.请求
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        
        // 设置请求头
        NSString *range = [NSString stringWithFormat:@"bytes=%lld-", self.currentLength];
        [request setValue:range forHTTPHeaderField:@"Range"];
        
        // 3.下载(创建完conn对象后,会自动发起一个异步请求)
        self.conn = [NSURLConnection connectionWithRequest:request delegate:self];
    } else { // 暂停
        [self.conn cancel];
        self.conn = nil;
    }
}
2>利用NSURLSession和它的代理方法
@property (nonatomic, strong) NSURLSessionDownloadTask *task;
@property (nonatomic, strong) NSData *resumeData;
@property (nonatomic, strong) NSURLSession *session;
//遵守NSURLSessionDownloadDelegate代理协议
- (NSURLSession *)session
{
    if (!_session) {
        // 获得session
        NSURLSessionConfiguration *cfg = [NSURLSessionConfiguration defaultSessionConfiguration];
        self.session = [NSURLSession sessionWithConfiguration:cfg delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    }
    return _session;
}

-(IBAction)download:(UIButton *)sender {
    // 按钮状态取反
    sender.selected = !sender.isSelected;
    
    if (self.task == nil) { // 开始(继续)下载
        if (self.resumeData) { // 恢复
            [self resume];
        } else { // 开始
            [self start];
        }
    } else { // 暂停
        [self pause];
    }
}

//从零开始
- (void)start
{
    // 1.创建一个下载任务
    NSURL *url = [NSURL URLWithString:@"http://192.168.15.172:8080/MJServer/resources/videos/minion_01.mp4"];
    self.task = [self.session downloadTaskWithURL:url];
    
    // 2.开始任务
    [self.task resume];
}
//恢复(继续)
- (void)resume
{
    // 传入上次暂停下载返回的数据,就可以恢复下载
    self.task = [self.session downloadTaskWithResumeData:self.resumeData];
    
    // 开始任务
    [self.task resume];
    
    // 清空
    self.resumeData = nil;
}
//暂停
- (void)pause
{
    __weak typeof(self) vc = self;
    [self.task cancelByProducingResumeData:^(NSData *resumeData) {
        //  resumeData : 包含了继续下载的开始位置\下载的url
        vc.resumeData = resumeData;
        vc.task = nil;
    }];
}

#pragma mark - NSURLSessionDownloadDelegate
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location
{
    NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    // response.suggestedFilename : 建议使用的文件名,一般跟服务器端的文件名一致
    NSString *file = [caches stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
   // 将临时文件剪切或者复制Caches文件夹
    NSFileManager *mgr = [NSFileManager defaultManager];
   [mgr moveItemAtPath:location.path toPath:file error:nil];
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
      didWriteData:(int64_t)bytesWritten
 totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
    NSLog(@"获得下载进度--%@", [NSThread currentThread]);
    // 获得下载进度
    self.progressView.progress = (double)totalBytesWritten / totalBytesExpectedToWrite;
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
 didResumeAtOffset:(int64_t)fileOffset
expectedTotalBytes:(int64_t)expectedTotalBytes
{
    
}

8 上传

1,文件上传的步骤

1.设置请求头
* 目的:告诉服务器请求体里面的内容并非普通的参数,而是包含了文件参数
[request setValue:@"multipart/form-data; boundary=标识" forHTTPHeaderField:@"Content-Type"];

2.设置请求体
* 作用:存放参数(文件参数和非文件参数)
1> 非文件参数
[body appendData:HMEncode(@"--标识\r\n")];
[body appendData:HMEncode(@"Content-Disposition: form-data; name=\"username\"\r\n")];

[body appendData:HMEncode(@"\r\n")];
[body appendData:HMEncode(@"张三")];
[body appendData:HMEncode(@"\r\n")];

2> 文件参数
[body appendData:HMEncode(@"--heima\r\n")];
[body appendData:HMEncode(@"Content-Disposition: form-data; name=\"file\"; filename=\"test123.png\"\r\n")];
[body appendData:HMEncode(@"Content-Type: image/png\r\n")];

[body appendData:HMEncode(@"\r\n")];
[body appendData:imageData];
[body appendData:HMEncode(@"\r\n")];

3> 结束标记 :参数结束的标记
[body appendData:HMEncode(@"--标识--\r\n")];

2,封装好的实例

=========================================封装好的实例=========================================
//filename要上传的文件名字,mimeType文件类型,fileDate上传的文件数据,通常是url获取文件地址,params是含有多参数的键值对的字典
eg:1,fileDate
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"autolayout" withExtension:@"txt"];
    NSData *data = [NSData dataWithContentsOfURL:url];
    2,params
        NSDictionary *params = @{
                             @"username" : @"李四",
                             @"pwd" : @"123",
                             @"age" : @30,
                             @"height" : @"1.55"
                             };
 
 
 
- (void)upload:(NSString *)filename mimeType:(NSString *)mimeType fileData:(NSData *)fileData params:(NSDictionary *)params
{
    // 1.请求路径
    NSURL *url = [NSURL URLWithString:@"xxxxx"];
    
    // 2.创建一个POST请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"POST";
    
    // 3.设置请求体
    NSMutableData *body = [NSMutableData data];
    
    // 3.1.文件参数,具体参数格式可以使用charles工具截取观察。\r\n硬性换行
    //str转换为data
    #define HMEncode(str) [str dataUsingEncoding:NSUTF8StringEncoding]
    #define HMNewLien @"\r\n"
    #define HMFileBoundary @"xxxxxxx"   标识
    
    [body appendData:HMEncode(@"--")];
    [body appendData:HMEncode(HMFileBoundary)];
    [body appendData:HMEncode(HMNewLien)];
    
    NSString *disposition = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"%@\"", filename];
    [body appendData:HMEncode(disposition)];
    [body appendData:HMEncode(HMNewLien)];
    
    NSString *type = [NSString stringWithFormat:@"Content-Type: %@", mimeType];
    [body appendData:HMEncode(type)];
    [body appendData:HMEncode(HMNewLien)];
    
    [body appendData:HMEncode(HMNewLien)];
    [body appendData:fileData];
    [body appendData:HMEncode(HMNewLien)];
    
    // 3.2.非文件参数
    /* [params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)
     *遍历parames这个字典的键值,有多少对,就自动遍历多少次
     */
    [params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        [body appendData:HMEncode(@"--")];
        [body appendData:HMEncode(HMFileBoundary)];
        [body appendData:HMEncode(HMNewLien)];
        
        NSString *disposition = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"", key];
        [body appendData:HMEncode(disposition)];
        [body appendData:HMEncode(HMNewLien)];
        
        [body appendData:HMEncode(HMNewLien)];
        [body appendData:HMEncode([obj description])];
        [body appendData:HMEncode(HMNewLien)];
    }];
    
    // 3.3.结束标记
    [body appendData:HMEncode(@"--")];
    [body appendData:HMEncode(HMFileBoundary)];
    [body appendData:HMEncode(@"--")];
    [body appendData:HMEncode(HMNewLien)];
    
    request.HTTPBody = body;
    
    // 4.设置请求头(告诉服务器这次传给你的是文件数据,告诉服务器现在发送的是一个文件上传请求)
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", HMFileBoundary];
    [request setValue:contentType forHTTPHeaderField:@"Content-Type"];
    
    // 5.发送请求
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
        NSLog(@"%@", dict);
    }];
}

ps:获取文件类型的方法MIMEType

1.百度搜索

2.查找服务器下面的某个xml文件
apache-tomcat-6.0.41\conf\web.xml

3.加载文件时通过Reponse获得
- (NSString *)MIMEType:(NSURL *)url
{
    // 1.创建一个请求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    // 2.发送请求(返回响应)
    NSURLResponse *response = nil;
    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
    // 3.获得MIMEType
    return response.MIMEType;
}

9,解压缩

一、技术方案
1.第三方框架:SSZipArchive
2.依赖的动态库:libz.dylib

二、压缩1
1.第一个方法
/**
 zipFile :产生的zip文件的最终路径
 directory : 需要进行的压缩的文件夹路径
 */
[SSZipArchive createZipFileAtPath:zipFile withContentsOfDirectory:directory];

2.第一个方法
/**
 zipFile :产生的zip文件的最终路径
 files : 这是一个数组,数组里面存放的是需要压缩的文件的路径的集合
 files = @[@"/Users/apple/Destop/1.png", @"/Users/apple/Destop/3.txt"]
 */
[SSZipArchive createZipFileAtPath:zipFile withFilesAtPaths:files];

三、解压缩
/**
 zipFile :需要解压的zip文件的路径
 dest : 解压到什么地方
 */
[SSZipArchive unzipFileAtPath:zipFile toDestination:dest];


10 AFNetwork

*一般只用于下载小文件

1,发送请求

一、2大管理对象
1.AFHTTPRequestOperationManager
* 对NSURLConnection的封装
2.AFHTTPSessionManager
* 对NSURLSession的封装

二、AFHTTPRequestOperationManager的具体使用
1.创建管理者
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
2.封装请求参数
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"username"] = @"哈哈哈";
params[@"pwd"] = @"123";
3.发送请求
NSString *url = @"http://localhost:8080/MJServer/login";
[mgr POST/GET:url parameters:params
  success:^(AFHTTPRequestOperation *operation, id responseObject) {
      // 请求成功的时候调用这个block
      //responseObject 如果是json数据,就默认解析为字典
      NSLog(@"请求成功---%@", responseObject);
  } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
      // 请求失败的时候调用调用这个block
      NSLog(@"请求失败");
  }];
  
三、对服务器返回数据的解析
1.AFN可以自动对服务器返回的数据进行解析
* 默认将服务器返回的数据当做JSON来解析
2.设置对服务器返回数据的解析方式
    1> 当做是JSON来解析(默认做法)
    * mgr.responseSerializer = [AFJSONResponseSerializer serializer];
    * responseObject的类型是NSDictionary或者NSArray

    2> 当做是XML来解析
    * mgr.responseSerializer = [AFXMLParserResponseSerializer serializer];
    * responseObject的类型是NSXMLParser

    3> 直接返回data
    * 意思是:告诉AFN不要去解析服务器返回的数据,保持原来的data即可
    * mgr.responseSerializer = [AFHTTPResponseSerializer serializer];
3.注意
* 服务器返回的数据一定要跟responseSerializer对得上

2,下载

   //AFNetwork的下载必须配合NSURLConnection或者NSURLSession才行
   
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    
    NSURL *URL = [NSURL URLWithString:@"http://www.baidu.com/img/bdlogo.png"];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
        NSLog(@"File downloaded to: %@", filePath);
    }];
    [downloadTask resume];

11 ASI

*功能十分强大,但已停止更新

3,上传

  //上传和下载基本相同,都是发送请求,但发送请求的方法不一样
  // 1.创建一个管理者
    AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
    
    // 2.封装参数(这个字典只能放非文件参数)
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    params[@"username"] = @"123";
    
    // 3.发送一个请求
    NSString *url = @"http://192.168.15.172:8080/MJServer/upload";
    [mgr POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        NSData *fileData = UIImageJPEGRepresentation(self.imageView.image, 1.0);
        [formData appendPartWithFileData:fileData name:@"file" fileName:@"haha.jpg" mimeType:@"image/jpeg"];

        // 不是用这个方法来设置文件参数
//        [formData appendPartWithFormData:fileData name:@"file"];
    } success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"上传成功");
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"上传失败");
    }];

4,监控网络状态

 
    AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];
    [mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        // 当网络状态发生改变的时候调用这个block
        switch (status) {
            case AFNetworkReachabilityStatusReachableViaWiFi:
                NSLog(@"WIFI");
                break;
                
            case AFNetworkReachabilityStatusReachableViaWWAN:
                NSLog(@"自带网络");
                break;
                
            case AFNetworkReachabilityStatusNotReachable:
                NSLog(@"没有网络");
                break;
                
            case AFNetworkReachabilityStatusUnknown:
                NSLog(@"未知网络");
                break;
            default:
                break;
        }
    }];
    // 开始监控
    [mgr startMonitoring];

其他:

1 NSMutableURLRequest的常用方法

1>.设置超时

request.timeoutInterval = 5;

* NSURLRequest是不能设置超时的,因为这个对象是不可变的

*NSMutableURLRequest并不代表就是post请求,也可以是get请求。系统默认是get请求,使用这个,代表url可改

九、URL转码

1.URL中不能包含中文,得对中文进行转码(加上一堆的%)

NSString *urlStr = @"http://localhost/login?username=喝喝&pwd=123";
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// urlStr == @"http://localhost/login?username=%E5%96%9D%E5%96%9D&pwd=123"





你可能感兴趣的:(iOS HTTP请求与解析)