- 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⃣️步骤
- 指定下载文件地址
- 指定文件保存路径
- 创建NSURLRequest
- 创建AFURLConnectionOperation
- 设置操作的输入流(网络上数据是以输入的形式传输)
- 设置下载进程处理块代码
- 操作完成块代码
- 启动操作
三、代码实现
#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