iOS开发:NSURLSession和Afnetworking的使用对比

为了学习iOS开发的网络知识,写了个demo对比原生和第三方网络库的用法。

预览







主要是写了两个页面,分别实现了get,post,上传,下载以及设置网络图片等功能等功能。

代码

NSURLSession的使用

NSURLConnection在iOS9被宣布弃用,NSURLSession是苹果在iOS7后为HTTP数据传输提供的一系列接口,比NSURLConnection强大,好用.

1 简单GET请求
// Simple Get
- (void)httpGetTest
{
    // Any url will be ok, here we use a little more complex url and params
    NSString *httpUrl = @"http://apis.baidu.com/thinkpage/weather_api/suggestion";
    NSString *httpArg = @"location=beijing&language=zh-Hans&unit=c&start=0&days=3";
    
    NSURLSession *session = [NSURLSession sharedSession];
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@?%@", httpUrl, httpArg]];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    // Add some extra params
    [request setHTTPMethod:@"GET"];
    [request addValue:@"7941288324b589ad9cf1f2600139078e" forHTTPHeaderField:@"apikey"];
    
    // Set the task, we can also use dataTaskWithUrl
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        // Do sth to process returend data
        if(!error)
        {
            NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        }
        else
        {
            NSLog(@"%@", error.localizedDescription);
        }
    }];
    
    // Launch task
    [dataTask resume];
}
  • 对于不需要额外的报文头的api,GET请求只要简单地把url拼起来穿进去就可以了(dataTaskWithUrl)
2  简单POST请求
// Simple Post
- (void)httpPostTest
{
    NSURL *url = [NSURL URLWithString:@"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"POST";
    request.HTTPBody = [@"date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213" dataUsingEncoding:NSUTF8StringEncoding];
    
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        // Do sth to process returend data
        if(!error)
        {
            NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        }
        else
        {
            NSLog(@"%@", error.localizedDescription);
        }
    }];
    [dataTask resume];
}
  • POST请求主要用于需要身份认证的网络接口
  • 必须是用request,在request里面添加很多选项和报文头
3  简单下载
// Simple Download
- (void)downLoadTest
{
    NSURL *url = [NSURL URLWithString:@"http://pic1.desk.chinaz.com/file/10.03.10/5/rrgaos56_p.jpg"];
    
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    // Use download with request or url
    NSURLSessionDownloadTask *downloadPhotoTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        // Move the downloaded file to new path
        NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
        [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:path] error:nil];
        // Set the image
        UIImage *downloadedImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:location]];
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"set the image");
//            self.imageView.image = downloadedImage; // set image from original location
            self.imageView.image = [UIImage imageWithContentsOfFile:path]; // set image from file system
        });
    }];

    [downloadPhotoTask resume];
}
  • 可以下载任何格式的文件,都是通过二进制传输
  • 设置图片,可以从原始地址也可以从文件系统中根据路径设置
  • 简单下载看不到下载进度
4  简单上传
// Simple Upload
- (void)upLoadTest
{
    NSURLSession *session = [NSURLSession sharedSession];
    // Set the url and params
    NSString *urlString = @"http://www.freeimagehosting.net/upload.php";
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    [request addValue:@"image/jpeg" forHTTPHeaderField:@"Content-Type"];
    [request addValue:@"text/html" forHTTPHeaderField:@"Accept"];
    [request setHTTPMethod:@"POST"];
    [request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
    [request setTimeoutInterval:20];
    
    //Set data to be uploaded
    UIImage *image = [UIImage imageNamed:@"beauty.jpg"];
    NSData *data = UIImageJPEGRepresentation(image, 1.0);
    
    // Use download from data or file
    NSURLSessionUploadTask *uploadPhotoTask = [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        // Do sth to process returend data
        if(!error)
        {
            NSLog(@"upload success");
            NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        }
        else
        {
            NSLog(@"%@", error.localizedDescription);
        }

    }];
    
    [uploadPhotoTask resume];
}
  • 上传可以从内存文件,沙盒文件系统,其他数据存储拿文件
  • 代码中的这个网站是用于测试上传的,需要校验,也可以自己搭建web服务器测试
5  代理方法的网络请求
// Url session delegate
- (void)UrlSessionDelegateTest
{
    NSString *httpUrl = @"http://apis.baidu.com/thinkpage/weather_api/suggestion";
    NSString *httpArg = @"location=beijing&language=zh-Hans&unit=c&start=0&days=3";
    // Set session with configuration, use this way to set delegate
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
                                                          delegate:self
                                                     delegateQueue:[[NSOperationQueue alloc] init]];
    
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@?%@", httpUrl, httpArg]];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    // Add some extra params
    [request setHTTPMethod:@"GET"];
    [request addValue:@"7941288324b589ad9cf1f2600139078e" forHTTPHeaderField:@"apikey"];
    
    // Set the task
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
    [dataTask resume];
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
    // Must allow the response of server, then we can receive data
    completionHandler(NSURLSessionResponseAllow);
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
    // Recevied data
    NSLog(@"data received---%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    if(!error)
    {
        NSLog(@"task completed!");
    }
    else
    {
        NSLog(@"%@", error.localizedDescription);
    }
}
  • 创建sesseion时需要用configuration,因为要设置委托
  • 接收到服务器响应后要允许接收后续的数据
  • 这种方法可以用于各种请求方式 GET, POST等
6  代理方法的下载
- (void)DownloadTaskTest
{
    NSURL *url = [NSURL URLWithString:@"http://pic1.desk.chinaz.com/file/10.03.10/5/rrgaos56_p.jpg"];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
                                                          delegate:self
                                                     delegateQueue:[[NSOperationQueue alloc] init]];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    // Use download with request or url
    NSURLSessionDownloadTask *downloadPhotoTask = [session downloadTaskWithRequest:request];
    
    [downloadPhotoTask resume];
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
    NSLog(@"set photo");
    NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
    [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:filePath] error:nil];
    
    dispatch_async(dispatch_get_main_queue(), ^{
        //Set image in the main thread
        self.imageView.image = [UIImage imageWithContentsOfFile:filePath];
    });
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
    // Compute the download progress
    CGFloat progress = 1.0 * totalBytesWritten / totalBytesExpectedToWrite;
    NSLog(@"%f",progress);
}
  • 可以通过委托函数获得实时下载进度

Afnetworking的使用

Afnetworking是一个非常流行(github上star很高)的ios网络插件,用起来方便,稳定,高效。

1  GET
// Test GET
- (void)httpGetTest
{
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer]; // Must add this code, or error occurs
    // Prepare the URL, parameters can be add to URL (could be html, json, xml, plist address)
//    NSString *url = @"https:github.com";
    NSString *url = @"http://zhan.renren.com/ceshipost";
    NSDictionary *params = @{@"tagId":@"18924", @"from":@"template"}; // Params can be nil
    
    [manager GET:url
      parameters:params
        progress:^(NSProgress * _Nonnull downloadProgress) {
            // Process the progress here
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            NSLog(@"%@", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]); // Can also parse the json file here
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"%@", error.localizedDescription);
        }];
}
  • 同样是有方法设置各种参数以及额外报文头的,比如通过manager去设置一些参数用于某些网站api校验,这里没有写出
2  POST
// Test POST
- (void)httpPostTest
{
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer]; // Must add this code, or error occurs
    // Prepare the URL and parameters
    NSString *url = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx";
    NSDictionary *params = [NSMutableDictionary dictionaryWithDictionary:@{@"date":@"20131129", @"startRecord":@"1", @"len":@"5", @"udid":@"1234567890", @"terminalType":@"Iphone", @"cid":@"213"}];
    
    [manager POST:url
       parameters:params
         progress:^(NSProgress * _Nonnull uploadProgress) {
             // Do sth to process progress
         } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
             NSLog(@"%@", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
         } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
             NSLog(@"%@", error.localizedDescription);
         }];
}
  • 与GET的差别只有一字之差
3  下载
// Test Download
- (void)downLoadTest
{
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
    // Set the download URL, could be any format file (jpg,zip,rar,png,mp3,avi.....)
    NSString *urlString = @"http://img.bizhi.sogou.com/images/1280x1024/2013/07/31/353911.jpg";
    NSURL *url = [NSURL URLWithString:urlString];
   
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
        NSLog(@"current downloading progress:%lf", 1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);
    } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        // The download address
        NSLog(@"default address%@",targetPath);
        // Set the real save address instead of the temporary address
        NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
        return [NSURL fileURLWithPath:filePath];
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        // When downloaded, do sth
        NSLog(@"%@ file downloaded to %@", response, [filePath URLByAppendingPathComponent:response.suggestedFilename]);
        // In the main thread, update UI
        dispatch_async(dispatch_get_main_queue(), ^{
            // Do sth to process UI
        });
        
    }];
    // Launch the download task
    [downloadTask resume];
}
  • 可以下载任意格式
  • 图片可以设置到UI里面去,但是注意要在主线程里做
  • 可以获得下载进度
4  上传
// Test Upload
- (void)upLoadTest
{
    // Can also use configuration initialize manager
//    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
//    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
    // Set the request
    NSString *urlString = @"http://www.freeimagehosting.net/upload.php";
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    [request addValue:@"image/jpeg" forHTTPHeaderField:@"Content-Type"];
    [request addValue:@"text/html" forHTTPHeaderField:@"Accept"];
    [request setHTTPMethod:@"POST"];
    [request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
    [request setTimeoutInterval:20];

    //Set data to be uploaded
    UIImage *image = [UIImage imageNamed:@"beauty.jpg"];
    NSData *data = UIImageJPEGRepresentation(image, 1.0);
    
    // Upload from data or file
    NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request
                                                               fromData:data
                                                               progress:^(NSProgress * _Nonnull uploadProgress) {
                                                                   NSLog(@"current uploading progress:%lf", 1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
                                                               } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
                                                                   // Do sth to response the success
                                                                   NSLog(@"%@", response);
                                                               }];
    // Launch upload
    [uploadTask resume];
}
  • 同样也是可以从内存、文件系统上传
5  监测网络状态
// Test the net state watching
- (void)watchNetState
{
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    /*
     typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
     AFNetworkReachabilityStatusUnknown          = -1,      unkown
     AFNetworkReachabilityStatusNotReachable     = 0,       offline
     AFNetworkReachabilityStatusReachableViaWWAN = 1,       cellular
     AFNetworkReachabilityStatusReachableViaWiFi = 2,       wifi
     };
     */
    
    // Once the network changed, this code works
    [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        switch(status)
        {
            case AFNetworkReachabilityStatusUnknown:
                NSLog(@"unkown");
                break;
            case AFNetworkReachabilityStatusNotReachable:
                NSLog(@"offline");
                break;
                
            case AFNetworkReachabilityStatusReachableViaWWAN:
                NSLog(@"cellular");
                break;
            case AFNetworkReachabilityStatusReachableViaWiFi:
                NSLog(@"wifi");
                break;
            default:
                NSLog(@"????");
                break;
        }
    }];
    // Must start monitoring
    [manager startMonitoring];
}
  • 执行了这段代码之后,程序就在监听设备的网络状况,只要网络改变就会有相应的响应
6  设置网络图片
// Test set url image
- (void)setUrlImage
{
    // Should include a header file, and the image willed cached automatically
    NSString *imgURL = @"http://img.article.pchome.net/00/44/28/57/pic_lib/wm/7.jpg";
    [self.imageView setImageWithURL:[NSURL URLWithString:imgURL] placeholderImage:nil];
}
  • 这个功能来自插件里面的一个category,Afnetworking很智能,能够直接设置网络上的图片到本地UI上并且自动创建缓存

下载

csdn: 网络demo
github: 网络demo




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值