关闭

OC-NSURLSession

标签: OCSession
48人阅读 评论(0) 收藏 举报
分类:

NSURLSession的基本概念:

三种工作方式:
默认会话模式(default):工作模式类似于原来的NSURLConnection,使用的是基于磁盘缓存的持久化策略,使用用户keychain中保存的整数进行认证授权。

瞬时会话模式(ephemeral)该模式不实用磁盘保存任何数据。所有和会话相关的caches,证书,cookies等都被保存在RAM中,因此当程序使会话无效,这些缓存的数据就会被自动清空。

后台会话模式(background):该模式在后台完成上传和下载,在创建Configuration对象的时候需要提供一个NSString类型的ID用于标识完成工作的后台会话。

NSURLSession支持的三种任务

加载数据 NSURLSessionDataTask
下载 NSURLSessionDownloadTask
上传 NSURLSessionUploadTask


NSURLSessionDataTask
使用协议实现

- (void)dataTask{

    //配置会话属性
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

    //创建任务对象(NSURLSession 使用 代理 或 block)
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    //通过url 创建dataTask
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"http://f.hiphotos.baidu.com/image/pic/item/e1fe9925bc315c60d916f9d58ab1cb134954770d.jpg"]];

    [dataTask resume];

}

书写代理的三个方法

//在书写方法之前,我们定义两个全局变量,分别用来接收数据和计算当前进度,以便创建进度条
//在UI上创建一个imgView以及progressView
@interface ViewController ()<NSURLSessionDataDelegate>
{
    NSMutableData *_mData;
    NSUInteger _expectedContenLenght;
}

@property (weak, nonatomic) IBOutlet UIImageView *imgView;

@property (weak, nonatomic) IBOutlet UIProgressView *progressView;

@end

任务收到响应


- (void)URLSession:(NSURLSession *)
  session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response  completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler{
    NSLog(@"收到响应");

    _mData = [NSMutableData data];

    //允许处理服务器的响应,才会继续接收服务器返回的数据
    completionHandler(NSURLSessionResponseAllow);

    _expectedContenLenght = response.expectedContentLength;

}

收到数据时回调的方法

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
    didReceiveData:(NSData *)data{
    NSLog(@"收到数据");
    [_mData appendData:data];

    //
    self.progressView.progress = (CGFloat) _mData.length / _expectedContenLenght;

}

task完成时实现的方法

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error{

    if (!error) {
        //回到主线程更新UI
        dispatch_async(dispatch_get_main_queue(), ^{
            self.imgView.image = [UIImage imageWithData:_mData];
        });
    }
}

用一个touchesBegan来调用方法

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [self dataTask2];
}

使用block实现

- (void)dataTask2{

    //配置会话属性
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

    //创建任务对象
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];

    //通过url创建DataTask
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"http://f.hiphotos.baidu.com/image/pic/item/e1fe9925bc315c60d916f9d58ab1cb134954770d.jpg"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (!error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                self.imgView.image = [UIImage imageWithData:data];
            });
        }
    }];
    [dataTask resume];
}

NSURLSessionUploadTask
以微博发送信息为例

- (void)uploadTask{
    //配置会话模式
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

    //将string编码后转成url
    NSString *urlString = @"https://api.weibo.com/2/statuses/update.json";
    urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSURL *url = [NSURL URLWithString:urlString];

    //创建任务对象
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];

    NSMutableURLRequest *mRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:60];

    NSString *bodyString = [NSString stringWithFormat:@"access_token=填入微博的相关API&status=%@",self.textField.text];
    NSData *bodyData = [bodyString dataUsingEncoding:4];

    [mRequest setHTTPMethod:@"POST"];
    [mRequest setHTTPBody:bodyData];

    NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:mRequest fromData:bodyData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (!error) {
            NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
            NSLog(@"%@",dictionary);
        }

    }];
    [uploadTask resume];
}

使用一个按钮来调用方法

- (IBAction)SendAction:(UIButton *)sender {
    [self uploadTask];
}

NSURLSessionDownloadTask,一般用于大文件下载
使用block实现,之后再用touchesBegan来调用,此处不演示

- (void)downloadTask1{
    //创建任务对象
    NSURLSession *session = [NSURLSession sharedSession];

    //创建下载任务
    //文件默认下载到tmp文件夹下,当下载完成后,如果没有做任何处理,会被删除,所以要在下载完成的时候将文件
    NSURLSessionUploadTask *downloadTask = [session downloadTaskWithURL:[NSURL URLWithString:@"http://c.hiphotos.baidu.com/image/pic/item/023b5bb5c9ea15ce9c017233b1003af33a87b219.jpg"] completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {

        if (!error) {
            //location.path
            NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, 1, YES)objectAtIndex:0];

            //建议使用的名字和服务器的名字一样
            NSString *fileName = response.suggestedFilename;
            NSString *filePath = [cachesPath stringByAppendingString:fileName];

            NSFileManager *fileManager = [NSFileManager defaultManager];
            [fileManager moveItemAtPath:location.path toPath:filePath error:nil];
        }
    }];
    [downloadTask resume];
}

使用协议实现下载以及断点下载

//我们声明三个全局变量,用于在不同方法间使用
@property (nonatomic,strong)NSURLSessionDownloadTask *downloadTask;
@property (nonatomic,strong)NSData *resumeData;
@property (nonatomic,strong)NSURLSession *sessionDownload;
- (void)downloadTask2{

    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

    self.sessionDownload = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    self.downloadTask = [self.sessionDownload downloadTaskWithURL:[NSURL URLWithString:@"http://b.zol-img.com.cn/desk/bizhi/image/7/2560x1600/145135666476.jpg"]];

    [self.downloadTask resume];
}

数据下载完成,此方法为必选方法

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location{

    //数据下载完成后保存到caches文件夹下
    NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)objectAtIndex:0];
    NSString *filePath = [cachesPath stringByAppendingPathComponent:downloadTask.response.suggestedFilename];

    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager moveItemAtPath:location.path toPath:filePath error:nil];
}

此方法用于显示当前下载进度条,此方法为可选方法

/*
 每当下载完一部分数据就会走这个方法

 session                    任务对象
 downloTask                 下载任务
 bytesWritten               本次写到文件里面的数据
 totalBytesWritten          已经写入到文件的数据
 totalBytesExpectedToWrite  文件总长度
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
    self.progressView.progress = (CGFloat)totalBytesWritten / totalBytesExpectedToWrite;
}

断点下载实现代码

- (IBAction)btnAction:(UIButton *)sender {
    if ([sender.titleLabel.text isEqualToString:@"下载"]) {

        [sender setTitle:@"暂停" forState:UIControlStateNormal];
        if (self.resumeData == nil) {
            [self downloadTask2];
        }
        else{
            self.downloadTask = [self.sessionDownload downloadTaskWithResumeData:self.resumeData];
            [self.downloadTask resume];
        }
    }

    else{
        [sender setTitle:@"下载" forState:UIControlStateNormal];
        [self.downloadTask cancelByProducingResumeData:^(NSData *resumeData) {
            self.resumeData = resumeData;

        }];
        self.downloadTask = nil;
    }
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1109次
    • 积分:157
    • 等级:
    • 排名:千里之外
    • 原创:15篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档