NSURLSession使用与AFNetWorking使用

介绍iOS中的两种网络编程。

NSURLSession

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{
    //解析服务器返回的数据
}

AFNetWorking

第三方框架,由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);
    }];
}
  1. 代理方法

你可能感兴趣的:(iOS知识典,http,网络,iOS,AFNetWorking,NSURLSession)