网络请求是IOS开发中必须具备的一种技能,在IOS开发中实现网络请求的四种方式,NSData,NSURLConnection,NSURLSession以及AFNetworking开源框架,此篇文章主要介绍相关类的用法。
一、使用NSData实现get请求
// 使用 NSData 请求网络数据 +(void)initWithData{ // 异步全局队列 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 使用NSData实现get请求 NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlpath]]; // 解析数据 id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil]; NSLog(@"%@",json); }); }
二、使用NSURLConnection类实现同步和异步请求
// 使用 NSURLConnection 请求数据 +(void)initWithURLConnection{ NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlpath]]; // 同步请求 NSURLResponse * response = nil; NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; id jsonData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil]; NSLog(@"%@",jsonData); // 异步请求 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { NSLog(@"%lu",(unsigned long)data.length); id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil]; NSLog(@"%@",json); }]; }
NSURLConnection类在IOS9.0时就被NSURLSession替代,而且NSURLSession类功能更强大。
三、NSURLSession实现网络请求
1、实现网络数据的请求,配置请求参照在NSURLRequest类中使用。
// 使用 NSURLSession 请求网络数据 +(void)initWithURLSession{ NSURL * url = [NSURL URLWithString:urlpath]; NSURLRequest * request = [NSURLRequest requestWithURL:url]; NSURLSession * session = [NSURLSession sharedSession]; // 方法一 NSURLSessionDataTask * dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil]; NSLog(@"%@",json); }]; // 任务默认挂起,调用resume方法启动 [dataTask resume]; }
2、实现网络文件的下载
// 下载数据 +(void)initWithDownloadTaskTest{ // 设置下载路径 NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:songPath]]; NSURLSession * session = [NSURLSession sharedSession]; // 开始下载 NSURLSessionDownloadTask * downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { // 设置本地下载路径 NSString * filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES)lastObject]; filePath = [filePath stringByAppendingPathComponent:@"/世间美好与你环环相扣.mp3"]; // 将下载完成的数据写入到指定位置 BOOL b =[[NSFileManager defaultManager]copyItemAtPath:location.path toPath:filePath error:nil]; if (b) { NSLog(@"success"); }else{ NSLog(@"failure"); } } ]; [downloadTask resume]; }
下载过程中展示进度
@interface ViewController () @property(nonatomic,strong)NSURLSession * session; @property(nonatomic,strong)NSURLSessionDownloadTask * task; @property(nonatomic,strong)NSData * resumeData; @property(nonatomic,strong)UISlider * slider; @end @implementation ViewController -(NSURLSession *)session{ if (!_session) { // 初始化 URLSession的行为和策略的配置对象 NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration]; _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]]; } return _session; } // 开始下载 -(void)startDownload{ NSURL * url = [NSURL URLWithString:@"http://www.fzydk.com/duoxingyun.mp3"]; self.task = [self.session downloadTaskWithURL:url]; [self.task resume]; } // 暂停 -(void)pauseDownload{ __weak typeof(self) weakSelf = self; [self.task cancelByProducingResumeData:^(NSData * _Nullable resumeData) { weakSelf.resumeData = resumeData; weakSelf.task = nil; }]; } // 恢复下载 -(void)resumeDownload{ self.task = [self.session downloadTaskWithResumeData:self.resumeData]; [self.task resume]; self.resumeData = nil; } // 下载发送错误,调用 -(void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error{ NSLog(@"%@",error); } // 下载进度 -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{ //获取下载进度 double pregress = (double)totalBytesWritten / totalBytesExpectedToWrite; [_slider setValue:pregress]; NSLog(@"%f",pregress); } // 恢复下载 -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{ } // 下载完成之后调用 -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{ // 将下载完成的数据缓存到本地 } - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor lightGrayColor]; UIButton * startBtn = [[UIButton alloc] initWithFrame:CGRectMake(100, 50, 100, 40)]; [startBtn setTitle:@"开始下载" forState:UIControlStateNormal]; [startBtn addTarget:self action:@selector(startDownload) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:startBtn]; UIButton * pauseBtn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 40)]; [pauseBtn setTitle:@"暂停下载" forState:UIControlStateNormal]; [pauseBtn addTarget:self action:@selector(pauseDownload) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:pauseBtn]; UIButton * resumeBtn = [[UIButton alloc] initWithFrame:CGRectMake(100, 200, 100, 40)]; [resumeBtn setTitle:@"恢复下载" forState:UIControlStateNormal]; [resumeBtn addTarget:self action:@selector(resumeDownload) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:resumeBtn]; // 进度条 _slider = [[UISlider alloc] initWithFrame:CGRectMake(10, 300, self.view.frame.size.width-20, 40)]; _slider.value = 0; _slider.minimumValue = 0; _slider.maximumValue = 1; [self.view addSubview:_slider]; } @end
3、NSURLSession实现文件上传
四、使用AFNetworking实现网络请求
1、GET和POST请求
-(void)getRequest{ // 方法一 // 发送Get请求 NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration]; _URLSessionManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:config]; NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlpath]]; [request setHTTPMethod:@"GET"]; NSURLSessionDataTask * dataTask = [_URLSessionManager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { NSLog(@"%@",responseObject); }]; [dataTask resume]; // 方法二 _HttpSessionManager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:config]; _HttpSessionManager = [AFHTTPSessionManager manager]; [_HttpSessionManager GET:urlpath parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { // 输出结果 NSLog(@"%@",responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"%@",error); }]; // 发送POST请求 [_HttpSessionManager POST:urlpath parameters:nil progress:^(NSProgress * _Nonnull uploadProgress) { NSLog(@"%@",uploadProgress.userInfo); } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"%@",responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"%@",error); }]; }
2、下载数据
-(void)downloadRequest{ NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration]; _HttpSessionManager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:config]; NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:songPath]]; NSURLSessionDownloadTask * task = [_HttpSessionManager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) { // 获取下载进度 double d1 = (double)downloadProgress.completedUnitCount; double d2 = (double)downloadProgress.totalUnitCount; NSLog(@"%.2f%%",d1/d2*100); } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) { // 返回资源本地存储的地址 NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil]; return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]]; } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) { NSLog(@"%@",filePath); }]; [task resume]; }
3、文件上传
-(void)uploadRequest{ _HttpSessionManager = [AFHTTPSessionManager manager]; // 方法一 NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:@""]]; NSURLSessionUploadTask * task = [_HttpSessionManager uploadTaskWithStreamedRequest:request progress:^(NSProgress * _Nonnull uploadProgress) { // 获取上传的进度 } completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { // 上传完成或上传失败之后回调 }]; [task resume]; // 方法二: NSdata 数据上传 [_HttpSessionManager uploadTaskWithRequest:request fromData:(nullable NSData *) progress:^(NSProgress * _Nonnull uploadProgress) { // 上传进度 } completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { // 上传回调 }]; // 方法三:本地文件上传 [_HttpSessionManager uploadTaskWithRequest:request fromFile:(nonnull NSURL *) progress:^(NSProgress * _Nonnull uploadProgress) { // 上传进度 } completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { // 上传回调 }] }