您的位置:首页 > 理论基础 > 计算机网络

iOS之网络—— NSURLSessionDataTask文件离线断点下载、NSURLSession文件上传、AFN基本使用、Cocoapods安装

2017-01-03 10:51 671 查看

1.使用NSURLSessionDataTask实现大文件离线断点下载(完整)

6.1 涉及知识点

(1)关于NSOutputStream的使用

//1. 创建一个输入流,数据追加到文件的屁股上
//把数据写入到指定的文件地址,如果当前文件不存在,则会自动创建
NSOutputStream *stream = [[NSOutputStream alloc]initWithURL:[NSURL fileURLWithPath:[self fullPath]] append:YES];

//2. 打开流
[stream open];

//3. 写入流数据
[stream write:data.bytes maxLength:data.length];

//4.当不需要的时候应该关闭流
[stream close];


(2)关于网络请求请求头的设置(可以设置请求下载文件的某一部分)

//1. 设置请求对象
//1.1 创建请求路径
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];

//1.2 创建可变请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

//1.3 拿到当前文件的残留数据大小
self.currentContentLength = [self FileSize];

//1.4 告诉服务器从哪个地方开始下载文件数据
NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentContentLength];
NSLog(@"%@",range);

//1.5 设置请求头
[request setValue:range forHTTPHeaderField:@"Range"];


(3)NSURLSession对象的释放

-(void)dealloc
{
//在最后的时候应该把session释放,以免造成内存泄露
//    NSURLSession设置过代理后,需要在最后(比如控制器销毁的时候)调用session的invalidateAndCancel或者resetWithCompletionHandler,才不会有内存泄露
//    [self.session invalidateAndCancel];
[self.session resetWithCompletionHandler:^{

NSLog(@"释放---");
}];
}


(4)优化部分

01 关于文件下载进度的实时更新
02 方法的独立与抽取


2.NSURLSession实现文件上传

7.1 涉及知识点

(1)实现文件上传的方法

/*
第一个参数:请求对象
第二个参数:请求体(要上传的文件数据)
block回调:
NSData:响应体
NSURLResponse:响应头
NSError:请求的错误信息
*/
NSURLSessionUploadTask *uploadTask =  [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error)


(2)设置代理,在代理方法中监听文件上传进度

/*
调用该方法上传文件数据
如果文件数据很大,那么该方法会被调用多次
参数说明:
totalBytesSent:已经上传的文件数据的大小
totalBytesExpectedToSend:文件的总大小
*/
-(void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
{
NSLog(@"%.2f",1.0 * totalBytesSent/totalBytesExpectedToSend);
}


(3)关于NSURLSessionConfiguration相关

01 作用:可以统一配置NSURLSession,如请求超时等
02 创建的方式和使用


//创建配置的三种方式
+ (NSURLSessionConfiguration *)defaultSessionConfiguration;
+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration;
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier NS_AVAILABLE(10_10, 8_0);

//统一配置NSURLSession
-(NSURLSession *)session
{
if (_session == nil) {

//创建NSURLSessionConfiguration
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];

//设置请求超时为10秒钟
config.timeoutIntervalForRequest = 10;

//在蜂窝网络情况下是否继续请求(上传或下载)
config.allowsCellularAccess = NO;

_session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
}
return _session;
}


3.AFN框架基本使用

8.1 AFN内部结构

AFN结构体
- NSURLConnection
+ AFURLConnectionOperation
+ AFHTTPRequestOperation
+ AFHTTPRequestOperationManager(封装了常用的 HTTP 方法)
* 属性
* baseURL :AFN建议开发者针对 AFHTTPRequestOperationManager 自定义个一个单例子类,设置 baseURL, 所有的网络访问,都只使用相对路径即可
* requestSerializer :请求数据格式/默认是二进制的 HTTP
* responseSerializer :响应的数据格式/默认是 JSON 格式
* operationQueue
* reachabilityManager :网络连接管理器
* 方法
* manager :方便创建管理器的类方法
* HTTPRequestOperationWithRequest :在访问服务器时,如果要告诉服务器一些附加信息,都需要在 Request 中设置
* GET
* POST

- NSURLSession
+ AFURLSessionManager
+ AFHTTPSessionManager(封装了常用的 HTTP 方法)
* GET
* POST
* UIKit + AFNetworking 分类
* NSProgress :利用KVO

- 半自动的序列化&反序列化的功能
+ AFURLRequestSerialization :请求的数据格式/默认是二进制的
+ AFURLResponseSerialization :响应的数据格式/默认是JSON格式
- 附加功能
+ 安全策略
* HTTPS
* AFSecurityPolicy
+ 网络检测
* 对苹果的网络连接检测做了一个封装
* AFNetworkReachabilityManager

建议:
可以学习下AFN对 UIKit 做了一些分类, 对自己能力提升是非常有帮助的


8.2 AFN的基本使用

(1)发送GET请求的两种方式(POST同)

-(void)get1
{
//1.创建AFHTTPRequestOperationManager管理者
//AFHTTPRequestOperationManager内部是基于NSURLConnection实现的
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

//2.发送请求
/* http://120.25.226.186:32812/login?username=ee&pwd=ee&type=JSON 第一个参数:NSString类型的请求路径,AFN内部会自动将该路径包装为一个url并创建请求对象
第二个参数:请求参数,以字典的方式传递,AFN内部会判断当前是POST请求还是GET请求,以选择直接拼接还是转换为NSData放到请求体中传递
第三个参数:请求成功之后回调Block
第四个参数:请求失败回调Block
*/

NSDictionary *param = @{
@"username":@"520it",
@"pwd":@"520it"
};

//注意:字符串中不能包含空格
[manager GET:@"http://120.25.226.186:32812/login" parameters:param success:^(AFHTTPRequestOperation * _Nonnull operation, id  _Nonnull responseObject) {

NSLog(@"请求成功---%@",responseObject);

} failure:^(AFHTTPRequestOperation * _Nonnull operation, NSError * _Nonnull error) {
NSLog(@"失败---%@",error);
}];
}

-(void)get2
{
//1.创建AFHTTPSessionManager管理者
//AFHTTPSessionManager内部是基于NSURLSession实现的
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

//2.发送请求
NSDictionary *param = @{
@"username":@"520it",
@"pwd":@"520it"
};

//注意:responseObject:请求成功返回的响应结果(AFN内部已经把响应体转换为OC对象,通常是字典或数组)
[manager GET:@"http://120.25.226.186:32812/login" parameters:param success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
NSLog(@"请求成功---%@",[responseObject class]);

} failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {
NSLog(@"失败---%@",error);
}];
}


(2)使用AFN下载文件

-(void)download
{
//1.创建一个管理者
AFHTTPSessionManager *manage  = [AFHTTPSessionManager manager];

//2.下载文件
/*
第一个参数:请求对象
第二个参数:下载进度
第三个参数:block回调,需要返回一个url地址,用来告诉AFN下载文件的目标地址
targetPath:AFN内部下载文件存储的地址,tmp文件夹下
response:请求的响应头
返回值:文件应该剪切到什么地方
第四个参数:block回调,当文件下载完成之后调用
response:响应头
filePath:文件存储在沙盒的地址 == 第三个参数中block的返回值
error:错误信息
*/

//2.1 创建请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_02.png"]];

//2.2 创建下载进度,并监听
NSProgress *progress = nil;

NSURLSessionDownloadTask *downloadTask = [manage downloadTaskWithRequest:request progress:&progress destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {

NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

//拼接文件全路径
NSString *fullpath = [caches stringByAppendingPathComponent:response.suggestedFilename];
NSURL *filePathUrl = [NSURL fileURLWithPath:fullpath];
return filePathUrl;

} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nonnull filePath, NSError * _Nonnull error) {

NSLog(@"文件下载完毕---%@",filePath);
}];

//2.3 使用KVO监听下载进度
[progress addObserver:self forKeyPath:@"completedUnitCount" options:NSKeyValueObservingOptionNew context:nil];

//3.启动任务
[downloadTask resume];
}

//获取并计算当前文件的下载进度
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(NSProgress *)progress change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
NSLog(@"%zd--%zd--%f",progress.completedUnitCount,progress.totalUnitCount,1.0 * progress.completedUnitCount/progress.totalUnitCount);
}


4.Cocoapods的安装

1.先升级Gem
sudo gem update --system
2.切换cocoapods的数据源
【先删除,再添加,查看】
gem sources --remove https://rubygems.org/ gem sources -a https://ruby.taobao.org/ gem sources -l
3.安装cocoapods
sudo gem install cocoapods
4.将Podspec文件托管地址从github切换到国内的oschina
【先删除,再添加,再更新】
pod repo remove master
pod repo add master http://git.oschina.net/akuandev/Specs.git pod repo add master https://gitcafe.com/akuandev/Specs.git pod repo update
5.设置pod仓库
pod setup
6.测试
【如果有版本号,则说明已经安装成功】
pod --version
7.利用cocoapods来安装第三方框架
01 进入要安装框架的项目的.xcodeproj同级文件夹
02 在该文件夹中新建一个文件Podfile
03 在文件中告诉cocoapods需要安装的框架信息
a.该框架支持的平台
b.适用的iOS版本
c.框架的名称
d.框架的版本
8.安装
pod install --no-repo-update
pod update --no-repo-update
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios Cocoapods 网络
相关文章推荐