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];

}

0 0
原创粉丝点击