介绍iOS中的两种网络编程。
iOS原生网络编程:支持后台下载上传、提供全局session、下载时是多线程异步处理效率更高。 使用上非常简单、创建一个请求Task然后执行。NSURLSessionTask有一些子类:NSURLSessionDataTask(发送常见的Get,Post请求)、NSURLSessionDownloadTask(发送下载请求)、NSURLSessionUploadTask(发送上传请求)
1. NSURLSession发送Get请求
过程:确认请求路径NSURL对象、创建请求对象NSURLRequest对象、创建会话对象NSURLSession、创建请求任务并执行、得到响应解析数据代码示例: //创建请求路径 NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://39.98.152.99:80/login?username=%@&password=%@",username,password]]; //创建请求对象 NSURLRequest *request = [NSURLRequest requestWithURL:url]; //获得会话对象 NSURLSession *session = [NSURLSession sharedSession]; //创建Task并执行,在block里接收返回数据 NSURLSessionTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if(error == nil) { //接收字符串数据 NSString *responseInfo = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; //接收字典类型 NSDictionary *responseInfo = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; }else{ NSLog(@"error:%@",error); } }]; [dataTask resume];2. NSURLSession发送Post请求
过程:确定请求路径(NSURL)、创建可变请求对象(NSMutableURLRequest)、设置请求方法与请求体、创建会话对象、创建请求任务并执行、响应后解析数据。代码示例 //确定请求路径 NSURL *url = [NSURL URLWithString:@"http://39.98.152.99:80/login"]; //创建可变请求对象 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //设置请求方法与请求体 request.HTTPMethod = @"POST"; request.HTTPBody = [@"username=jack&password=123" dataUsingEncoding:NSUTF8StringEncoding]; //创建会话对象 NSURLSession *session = [NSURLSession sharedSession]; //创建Task并执行 NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { }];3. 使用代理完成请求 监听网络请求的过程,需要遵守协议并实现代理方法。
确定请求路径 NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://39.98.152.99:80/login?username=%@&password=%@",username,password]]; 创建请求对象 NSURLRequest *request = [NSURLRequest requestWithURL:url]; 获得会话对象并设置代理 第三个参数决定代理方法在哪个线程中调用,[[NSOperationQueue alloc] init]则在子线程中调用,示例为主线程。 NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]]; 遵从协议并设置接收信息的变量。 @interface LoginViewController ()<NSURLSessionDataDelegate> @property (nonatomic, strong) NSMutableData *mData; @end 创建Task并执行 NSURLSessionDataTask *task = [session dataTaskWithRequest:request]; [task resume]; 代理方法的实现 //收到服务器响应的时候调用 -(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{ //打印http信息 NSHTTPURLResponse *htttpResponse = (NSHTTPURLResponse *)response; NSLog(@"响应头:%@",htttpResponse.allHeaderFields); //定义一个容器用于接受服务器返回的数据 self.mData = [NSMutableData data]; //收到响应信息之后,需要使用completionHandler回调告诉系统应该如何处理服务器返回的数据 //默认是取消的(NSURLSessionResponseCancel),继续传递数据(NSURLSessionResponseAllow) completionHandler(NSURLSessionResponseAllow); } //收到服务器返回数据的时候会调用 - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{ [_mData appendData:data]; } //请求完成(成功|失败)的时候会调用 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{ //解析服务器返回的数据 }第三方框架,由NSURLSession(AFURLSessionManager、AFHTTPSeesionManager)、Serialization( 协议、 协议)、AFSecurityPolicy(安全)、其他缓存。 1. AFURLSessionManager(和NSURLSession很相似)
普通数据任务 NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; NSURL *URL = [NSURL URLWithString:@"http://httpbin.org/get"]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { if (error) { NSLog(@"Error: %@", error); } else { NSLog(@"%@ %@", response, responseObject); } }]; [dataTask resume]; 下载任务 NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; //创建请求对象 NSURL *URL = [NSURL URLWithString:@"http://example.com/download.zip"]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; //创建任务 NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response){ NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil]; return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]]; }completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) { NSLog(@"File downloaded to: %@", filePath); }]; //启动任务 [downloadTask resume]; 上传任务 NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; NSURL *URL = [NSURL URLWithString:@"http://example.com/upload"]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"]; NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { if (error) { NSLog(@"Error: %@", error); } else { NSLog(@"Success: %@ %@", response, responseObject); } }]; [uploadTask resume];2. AFHTTPSeesionManager、是封装的子类,更便捷(推荐)。
发送Get请求 //1.创建AFHTTPSessionManager管理者(内部是基于NSURLSession实现) AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //2.发送请求 NSDictionary *param = @{@"username":@"520it",@"pwd":@"520it"}; [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); }]; //responseObject是请求成功返回的响应结果、通常是字典或数组 下载文件 -(void)download { //创建一个管理者 AFHTTPSessionManager *manage = [AFHTTPSessionManager manager]; //创建请求对象 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_02.png"]]; //创建下载进度并监听 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); }]; //参数:请求对象、下载进度、block回调,返回下载文件的目标地址、下载完成之后调用的block //使用KVO监听下载进度 [progress addObserver:self forKeyPath:@"completedUnitCount" options:NSKeyValueObservingOptionNew context:nil]; [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); } 上传文件 -(void)upload { AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //发送POST请求上传数据 NSDictionary *dict = @{ @"username":@"wenidngding" }; [manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) { //把本地的图片转换为NSData类型的数据 UIImage *image = [UIImage imageNamed:@"123"]; NSData *data = UIImagePNGRepresentation(image); [formData appendPartWithFileData:data name:@"file" fileName:@"xxoo.png" mimeType:@"application/octet-stream"]; } success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) { NSLog(@"请求成功---%@",responseObject); } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) { NSLog(@"请求失败--%@",error); }]; }另一种上传请求根据url确定文件
-(void)upload2 { //1.创建一个请求管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; NSDictionary *dict = @{ @"username":@"wenidngding" }; [manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) { //本地文件的url NSURL *fileUrl = [NSURL fileURLWithPath:@"/Users/文顶顶/Desktop/KF[WTI`AQ3T`A@3R(B96D89.gif"]; [formData appendPartWithFileURL:fileUrl name:@"file" error:nil]; } success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) { NSLog(@"请求成功---%@",responseObject); } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) { NSLog(@"请求失败--%@",error); }]; } 代理方法