• iOS里面实现断点续传
  • 第三方框架之AFN
  • 代码实现

一、iOS里面实现断点续传



1⃣️AFN基于NSURL



1.性能和稳定性略差。针对JSON、XML、Plist和Image四种数据结构封装了各自处理器



2.适合逻辑简单的应用,易用性好



2⃣️ASI基于CFNetwork(更底层)



1.性能和稳定性略高,没有针对任何一种数据类型做封装



2.适合已经发展了一段时间的应用


二、第三方框架AFN



1⃣️操作



1.拖入AFN框架文件,编译(两个警告,需要倒入框架)



2.倒入System~, Mobile~



3.Supporting File文件修改.pch文件,#import一下上面两个框架



2⃣️步骤



  1. 指定下载文件地址
  2. 指定文件保存路径
  3. 创建NSURLRequest
  4. 创建AFURLConnectionOperation
  5. 设置操作的输入流(网络上数据是以输入的形式传输)
  6. 设置下载进程处理块代码
  7. 操作完成块代码
  8. 启动操作




三、代码实现



#pragma mark - 下载文件
- (IBAction)downloadFiles:(id)sender
{
    // 1.   指定下载文件地址
    NSURL *url = [NSURL URLWithString:@"http://169.254.98.245/download/iTunesConnect_DeveloperGuide_CN.zip"];
    // 2.   指定文件保存路径
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *downloadPath = [documents[0]stringByAppendingPathComponent:@"book.zip"];
    // 3.   创建NSURLRequest
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    // 4.   创建AFURLConnectionOperation
    AFURLConnectionOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:request];
    
    // 5.   设置操作的输出流(在网络中的数据是以流的方式传输的,告诉操作把文件保存在第2步设置的路径中)
    [operation setOutputStream:[NSOutputStream outputStreamToFileAtPath:downloadPath append:NO]];
    // 6.   设置下载进程处理块代码
    // 6.1 bytesRead 读取的字节——这一次下载的字节数
    // 6.2 totalBytesRead 读取的总字节——已经下载完的
    // 6.3 totalBytesExpectedToRead 希望读取的总字节——就是文件的总大小
    [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
        // 做下载进度百分比的工作
        NSLog(@"下载百分比:%f", (float)totalBytesRead / totalBytesExpectedToRead);
    }];
    // 7.   操作完成块代码
    [operation setCompletionBlock:^{
        // 解压缩的顺序
        // 1. 定义要解压缩的文件 —— downloadPath
        // 2. 要解压缩的目标目录
        // 3. 调用类方法解压缩
        [SSZipArchive unzipFileAtPath:downloadPath toDestination:documents[0]];
        
        // 删除压缩包
        [[NSFileManager defaultManager]removeItemAtPath:downloadPath error:nil];
    }];
    
    // 8   启动操作
    [operation start];
}



//
//  ViewController.m
//  AFN框架
//
//  Created by apple on 14-6-21.
//  Copyright (c) 2014年 Early. All rights reserved.
//

#import "ViewController.h"
#import "AFNetworking.h"

@interface ViewController () <NSXMLParserDelegate>
{
    NSOperationQueue *_queue;
    
    UIImageView *_imageView;
}
@end

@implementation ViewController

/**
 1.在Linux系统上,运行的Web服务器叫做Apache
 2.所有的http访问都是基于html或者相关的文件,例如:php,asp,jsp,asp.net
 3.form,在html页面中又称表单,用来提交页面的,所有post请求的页面,至少会有一个表单
 4.get/post,get是拿数据,post是将数据体放置在表单中提交给服务器,然后服务器再响应
 */

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    _queue = [[NSOperationQueue alloc] init];
    
    //1.检测连接状态
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    btn.frame = CGRectMake(100, 100, 100, 50);
    [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [btn setTitle:@"链接状态" forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(reach) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
    
    //2.JSON解析
    UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeCustom];
    btn2.frame = CGRectMake(100, 150, 100, 50);
    [btn2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [btn2 setTitle:@"加载JSON" forState:UIControlStateNormal];
    [btn2 addTarget:self action:@selector(loadJSON) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn2];
    
    //3.XML解析
    UIButton *btn3 = [UIButton buttonWithType:UIButtonTypeCustom];
    btn3.frame = CGRectMake(100, 200, 100, 50);
    [btn3 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [btn3 setTitle:@"加载XML" forState:UIControlStateNormal];
    [btn3 addTarget:self action:@selector(loadXML) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn3];
    
    //4.UIImageView
    UIButton *btn4 = [UIButton buttonWithType:UIButtonTypeCustom];
    btn4.frame = CGRectMake(100, 250, 100, 50);
    [btn4 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [btn4 setTitle:@"加载UIImageView" forState:UIControlStateNormal];
    [btn4 addTarget:self action:@selector(loadImageView) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn4];
    
    //5.上传文件
    UIButton *btn5 = [UIButton buttonWithType:UIButtonTypeCustom];
    btn5.frame = CGRectMake(100, 300, 100, 50);
    [btn5 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [btn5 setTitle:@"上传图像" forState:UIControlStateNormal];
    [btn5 addTarget:self action:@selector(postImage) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn5];
    //6.断点续传
}

#pragma mark - 上传图像
- (void)postImage
{
    //1.定义HttpClient
    NSURL *url = [NSURL URLWithString:@"地址"];
    AFHTTPClient *httpClient = [AFHTTPClient clientWithBaseURL:url]; //baseUrl后边的请求都基于这个地址
    
    //2.根据HttpClient生成一个post请求
    NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:@"POST" path:@"后续地址" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
       //formData就是上传的数据
        NSData *data = UIImagePNGRepresentation(_imageView.image);
        /**
         1.要上传文件的参数
         2.负责上传文件的远处服务中接受文件使用的参数
         3.要上传文件的文件名(别人告知)
         4.要上传文件的文件类型(别人告知)
         */
        [formData appendPartWithFileData:data name:@"file" fileName:@"upload001.png" mimeType:@"image/png"];
    }];
    
    //3.准备做上传的操作
    AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"上传文件成功");
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"上传文件失败");
    }];
    
    [op start];
}

#pragma mark - 加载UIImageView
//如果异步在家表格图像,不建议使用
- (void)loadImageView
{
    //1.创建一个UIImageView
    _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 0, 50, 50)];
    [self.view addSubview:_imageView];
    
    //2.URL
    NSURL *url = [NSURL URLWithString:@"图片地址"];
    [_imageView setImageWithURL:url placeholderImage:[UIImage imageNamed:@""]];
}

#pragma mark - 加载XML
- (void)loadXML
{
    //1.URL
    NSURL *url = [NSURL URLWithString:@"地址"];
    
    //2.Request
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    //3.Connection(默认在主队列,可以新建一个队列放入,不影响主界面)
    AFXMLRequestOperation *op = [AFXMLRequestOperation XMLParserRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) {
        NSLog(@"加载XML成功");
        
        //1.实例化解析器,并传入数据 AFN已经做了 XMLParser
        //2.设置代理
        [XMLParser setDelegate:self];
        //3.解析器解析
        [XMLParser parse];
        
    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLParser *XMLParser) {
        NSLog(@"加载XML失败");
    }];
    
    [_queue addOperation:op];
}
#pragma mark - XML解析器代理方法(6个)
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
    
}

#pragma mark - 加载JSON
- (void)loadJSON
{
    //1.URL
    NSURL *url = [NSURL URLWithString:@"地址"];
    
    //2.Request
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    //3.Connection(默认在主队列,可以新建一个队列放入,不影响主界面)
    AFJSONRequestOperation *op = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        NSLog(@"成功加载JSON");
    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        NSLog(@"失败加载JSON");
    }];
    
    [op start];
}

#pragma mark - 检测连接状态
- (void)reach
{
    //链接状态的检测
    NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
    AFHTTPClient *httpClient = [AFHTTPClient clientWithBaseURL:url];
    
    [httpClient setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        switch (status) {
            case AFNetworkReachabilityStatusNotReachable:
                NSLog(@"无链接");
                break;
                
            case AFNetworkReachabilityStatusReachableViaWiFi:
                NSLog(@"Wifi");
                break;
                
            case AFNetworkReachabilityStatusReachableViaWWAN:
                NSLog(@"3G链接");
                break;
                
            default:
                NSLog(@"链接状态未知");
                break;
        }
    }];
}

@end