iOS开发 - 同步异步下载
来源:互联网 发布:python 写入txt文件 编辑:程序博客网 时间:2024/04/29 20:19
同步请求
1.
//这种方式请求和响应都包含在内
NSData * data =[NSData dataWithContentsOfURL:url];
2.
//请求类
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:str]];
//响应类
NSURLResponse * response = nil;
//NSError 报错类
NSError * error = nil;
//发送请求
NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
//发送请求成功 服务器会给我们发响应 response/报错信息 error
异步请求
1.GET请求
//GET请求 没有设置请求方式 默认是get请求
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:path] cachePolicy:0 timeoutInterval:10];
//发送异步请求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
//解析过程
id obj = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(@”%@”,obj);
}];
//queue 队列/线程
//程序运行会有一个主线程 所有UI的操作都是主线程在做
//[NSOperationQueue mainQueue] 主线程
//completionHandler 返回数据 响应成功 通过block把数据返回回来
2.NSURLConnection Block
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
//设置请求方式
request.HTTPMethod = @”POST”;
//参数放到请求体里面
NSString * str = @”page=1&number=20”;
request.HTTPBody = [str dataUsingEncoding:NSUTF8StringEncoding];
//发送请求[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { //解析 id obj = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];}];
3.NSURLConnection 协议代理
NSURL * url = [NSURL URLWithString:str];NSURLRequest * request = [NSURLRequest requestWithURL:url];//发送请求[NSURLConnection connectionWithRequest:request delegate:self];*******************协议方法*************
//发送请求成功 服务器响应 会调用这个方法
-(void)connection:(NSURLConnection )connection didReceiveResponse:(NSURLResponse )response{
NSLog(@”%@”,response);
NSHTTPURLResponse * urlResponse = (id)response;
if (urlResponse.statusCode == 200) {
self.muData = [[NSMutableData alloc] init];
}
//清空可变dataself.muData.length = 0;
}
//接收数据会调用这个方法 接收数据是一段一段的 这个方法会被反复调用 数据越大调用次数越多
-(void)connection:(NSURLConnection )connection didReceiveData:(NSData )data{
NSLog(@"接收到数据");[self.muData appendData:data];
}
//接收数据完毕
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
id obj = [NSJSONSerialization JSONObjectWithData:self.muData options:NSJSONReadingMutableContainers error:nil];NSLog(@"%@",obj);
}
//错误
-(void)connection:(NSURLConnection )connection didFailWithError:(NSError )error{
NSLog(@"%@",error);
}
4.NSURLSession
NSURLSession的基本设置
NSURLRequest *request = [NSURLRequest requestWithURL:url];//配置对象NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration];//会话对象NSURLSession * session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];//普通任务NSURLSessionDataTask * task = [session dataTaskWithRequest:request];[task resume];
NSURLSession的协议方法
//响应成功 调用该方法
-(void)URLSession:(NSURLSession )session dataTask:(NSURLSessionDataTask )dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
NSLog(@”%@”,response);
//清空可变data容器self.muData.length = 0;//****这个block必须要调用****completionHandler(NSURLSessionResponseAllow);/* NSURLSessionResponseCancel = 0, //取消接收数据 NSURLSessionResponseAllow = 1, //继续下载数据 NSURLSessionResponseBecomeDownload = 2, //把数据变成下载 NSURLSessionResponseBecomeStream //变成数据流*/
}
//这个方法会被多次调用 接收数据会调用这个方法 数据返回的时候是一段一段的
-(void)URLSession:(NSURLSession )session dataTask:(NSURLSessionDataTask )dataTask didReceiveData:(NSData *)data{
//拼接数据
[self.muData appendData:data];
}
//不管下载成功或失败 都会调用这个方法
-(void)URLSession:(NSURLSession )session task:(NSURLSessionTask )task didCompleteWithError:(NSError *)error{
if (error) { NSLog(@"%@",error);}else{ //下载成功 解析数据 id obj = [NSJSONSerialization JSONObjectWithData:self.muData options:NSJSONReadingMutableContainers error:nil]; NSLog(@"%@",obj);}
}
NSURLSession Block写法
1.普通任务
//创建session(会话)对象//创建的是单例对象 这种方式和使用NSURLConnection是一样的NSURLSession * session = [NSURLSession sharedSession];//NSURLSessionDataTask普通下载NSURLSessionDataTask * task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { //data我们需要的数据 response响应对象 error报错信息 //解析数据}];//completionHandler 响应成功 数据回调的时候会调用这个方法//执行任务 发送请求[task resume];
2.普通任务
NSURLRequest *request = [NSURLRequest requestWithURL:url];// NSURLSessionConfiguration工作配置NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration];//defaultSessionConfiguration 默认配置//ephemeralSessionConfiguration 瞬时会话模式 不考虑缓存配置//backgroundSessionConfigurationWithIdentifier:@"id" 后台配置//参数 标识符 可以区分多个后台多个下载任务//设置超时时间config.timeoutIntervalForRequest = 10.0;//允许使用移动蜂窝网络config.allowsCellularAccess = YES;//根据电量选择网络,电量充足会选择合适的网络config.discretionary = YES;//创建会话对象NSURLSession * session = [NSURLSession sessionWithConfiguration:config];NSURLSessionDataTask * task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { id obj = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; NSLog(@"%@",obj);}];//执行[task resume];
3.数据下载
NSURLRequest * request = [NSURLRequest requestWithURL:url];NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:config];NSURLSessionDownloadTask * downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) { //下载的数据会存放到默认缓存的位置 任务一结束 缓存被清空 NSString * str = NSHomeDirectory(); //存放路径+文件名 NSString * path = [str stringByAppendingPathComponent:@"library/text.txt"]; //把本地路径转成NSURL对象 NSURL * url1 = [NSURL fileURLWithPath:path]; //将数据写在本地的路径下}];//执行下载任务[downloadTask resume];
4.数据上传
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:@""]]; NSURLSession * session = [NSURLSession sessionWithConfiguration:config];//第二个参数(fromData) 为需要上传的数据NSURLSessionUploadTask * task = [session uploadTaskWithRequest:request fromData:nil completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { //返回的第一个参数 是否上传成功 用户id信息等 即服务器返回的数据 //解析}];//执行任务[task resume];
5.普通下载
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:URL]];NSProgress * progress = nil;NSURLSessionDownloadTask * task =[manager downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) { // destination 这个block需要返回一个NSURL 本地存储文件的url地址 // 参数 targetPath 缓存url //正常情况下 可需要把文件放到沙盒目录下 NSString * path = @"/Users/qianfeng/Desktop/QQ.dmg"; //fileURLWithPath 拿到的是本地URL的路径 return [NSURL fileURLWithPath:path];} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) { //任务完成的时候调用 NSLog(@"%@ %@",error,[NSString stringWithContentsOfURL:filePath encoding:NSUTF8StringEncoding error:nil]);}];//观察进度//NSProgress的属性--fractionCompleted 完成进度[progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:nil];[task resume];
6.断点续传 Demo
功能实现: 点击开始按钮 开始下载 ,点击暂停,停止下载 再次点击开始的时候继续下载。当程序中断退出再次进入的时候,可以继续上次的内容下载。
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIButton *startBtn;
@property (weak, nonatomic) IBOutlet UIButton *stopBtn;
@property (weak, nonatomic) IBOutlet UILabel *proLabel;
@property (weak, nonatomic) IBOutlet UIProgressView *progress;
@property (nonatomic,strong) NSURLSessionDataTask *task;
@property (nonatomic,assign) unsigned long long nowSize;//当前下载文件的大小 文件的字节数
@property (nonatomic,assign) unsigned long long fileSize;//总的文件的大小/字节数
@property (nonatomic,strong) NSFileHandle * handle;
@end
@implementation ViewController
(void)viewDidLoad {
[super viewDidLoad];
self.nowSize = 0;[self addObserver:self forKeyPath:@”nowSize” options:NSKeyValueObservingOptionNew context:nil];
//读取本地总的字节数
self.fileSize = [[[NSUserDefaults standardUserDefaults] objectForKey:@”fileSize”] integerValue];
//当前已下载的字节数
//NSFileManager 是一个单例对象
NSFileManager * manager = [NSFileManager defaultManager];
//fileExistsAtPath 当前路径下的文件是否存在
if (![manager fileExistsAtPath:@”/Users/qianfeng/Desktop/QQ1.dmg”]) {
[manager createFileAtPath:@”/Users/qianfeng/Desktop/QQ1.dmg” contents:nil attributes:nil];
}
NSDictionary * dic = [manager attributesOfItemAtPath:@”/Users/qianfeng/Desktop/QQ1.dmg” error:nil];
//当前已经下载的字节数
self.nowSize = [dic[@”NSFileSize”] integerValue];
}(IBAction)onClickStart:(id)sender {
NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession * session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URL]];
//设置请求头—RANGE
[request setValue:[NSString stringWithFormat:@”bytes=%lld-“,self.nowSize] forHTTPHeaderField:@”RANGE”];self.task = [session dataTaskWithRequest:request];
[self.task resume];
//开始按钮停止点击功能
[sender setEnabled:NO];
}(IBAction)onClickStop:(id)sender {
[self.startBtn setEnabled:YES];
[self.task cancel];
}
//请求成功 收到响应的时候
-(void)URLSession:(NSURLSession )session dataTask:(NSURLSessionDataTask )dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
//NSURLResponse 响应对象 NSHTTPURLResponse是NSURLResponse的子类 allHeaderFields拿到所有的响应头
NSDictionary * dic = [(NSHTTPURLResponse *)response allHeaderFields];
NSLog(@”收到数据…%@”,dic);
unsigned long long lastSize = [dic[@"Content-Length"] intValue];//总大小self.fileSize = lastSize + self.nowSize;//将总的大小存在本地NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];[defaults setValue:@(self.fileSize) forKey:@"fileSize"];[defaults synchronize];//NSFileHandle写文件self.handle = [NSFileHandle fileHandleForUpdatingAtPath:@"/Users/qianfeng/Desktop/QQ1.dmg"];//定位到文件尾部 每一次都是接着上一次写[self.handle seekToEndOfFile];//必须调用这个blockcompletionHandler(NSURLSessionResponseAllow);
}
//实时拿到数据
-(void)URLSession:(NSURLSession )session dataTask:(NSURLSessionDataTask )dataTask didReceiveData:(NSData *)data{
NSLog(@”拿到数据…”);
//计算当前下载的数据大小
self.nowSize += data.length;
//写文件
[self.handle writeData:data];
}
-(void)URLSession:(NSURLSession )session task:(NSURLSessionTask )task didCompleteWithError:(NSError *)error{
//关闭写文件
[self.handle closeFile];
if (error) {
self.startBtn.enabled = YES;
NSLog(@”%@”,error);
}
else{
NSLog(@”下载完成”);
}
}
//观察数据变化
-(void)observeValueForKeyPath:(NSString )keyPath ofObject:(id)object change:(NSDictionary )change context:(void *)context{
float value = self.nowSize*1.0/self.fileSize;self.progress.progress = value;self.proLabel.text = [NSString stringWithFormat:@"%.2f%%",value*100];
}
- iOS开发 - 同步异步下载
- ios网络开发 同步下载和异步下载
- ios网络开发 同步下载和异步下载
- ios网络开发 同步下载和异步下载
- ios 同步和异步下载
- IOS的同步下载及异步下载
- ios-同步下载与异步下载
- ios-同步下载与异步下载
- ios-同步下载与异步下载
- iOS开发同步下载
- ios 同步和异步下载图片
- ios-同步下载,异步下载,S…
- iOS 同步,异步,普通 三种方式下载
- 同步、异步下载
- 同步下载和异步下载
- 同步下载和异步下载
- 同步下载与异步下载
- ios 同步异步消息
- 查表空间对应的数据文件
- (java)两个队列实现栈的操作
- [Java] char、byte类型
- 阅读Android源码的一些姿势
- redhat7 网络安装 Kickstart
- iOS开发 - 同步异步下载
- 查对象创建日期
- IntelliJ idea导出web项目手工部署到tomcat
- java微信开发actoken存储方案
- AsyncTask引发的问题
- Hibernate中的自定义类型——UserType、CompositeUserType
- 琐碎积累
- HIBERNATE与 MYBATIS的对比
- sqlite创建表成功,insert不报错,但没有数据插入