要实现网络数据的下载与上传,主要有三种方式

> NSURLConnection  针对少量数据,使用“GET”或“POST”方法从服务器获取数据,使用“POST”方法向服务器传输数据;

> NSURLSession(ios7.0新推出的) 针对大量数据,可使用“GET”方法实现线程安全的多线程下载,监控下载进度等,也可以使用“PUT”方法实现上传[put 方法存在严重的安全隐患,目前很少有服务器支持此种上传方式];

> AFNetWorking(2.0之前的版本) 对NSURLConnection进行封装的第三方开源框架,实现了大量数据的下载与上传,但是对于线程安全没有较好的控制措施;


推荐用法:对于少量数据(例如平时的网页信息)的下载与上传,直接使用NSURLConnection,对于大量数据的下载使用NSURLSession,对于大量数据的上传使用AFNetWorking

NSURLConnection:

  1> GET

// 1. 定义URL,确定要访问的地址
NSURL *url = [NSURL URLWithString:urlString];
// 2. 定义URLRequest,确定网络访问请求,在GET方法中直接用URL即可
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:2.0f]; //===================================================
NSURLResponse *response = nil;
NSError *error = nil;
// 同步请求的应用场景:例如:网银账户的登录!
// 一定要获取到某个网络返回数据后,才能进行下一步操作的场景! // 发送同步请求,respone&error要带地址的原因就是为了方法执行后,能够方便使用response&error
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
//-------------------------------------------------
// 发送异步请求[有同步则不需要异步,反之亦然]
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// 块代码的内容会在网络访问后执行
// 块代码是预先定义好的代码片段,在满足某个条件时执行的。
NSLog(@"%@", [NSThread currentThread]);
}];

  2> POST

// 1. 定义URL,确定要访问的地址
NSURL *url = [NSURL URLWithString:urlString];
// 2. 定义请求,生成数据体添加到请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 1) 指定网络请求的方法
request.HTTPMethod = @"POST"; // 2) 生成数据体
// * 先生成字符串
NSString *bodyStr = [NSString stringWithFormat:@"username=%@&password=%@", userName, password];
// * 将字符串转换成NSData
request.HTTPBody = [bodyStr dataUsingEncoding:NSUTF8StringEncoding]; // 提示:POST请求多用于用户登录,或者上传文件,在实际开发中,“POST请求的参数及地址”需要与公司的后端程序员沟通。
// POST同样具备同步和异步方法,与get中同步异步方法相同

NSURLSession

     // url
NSURL *url = [NSURL URLWithString:strURL]; // request
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:3.0f]; // session
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]]; _downloadTask = [session downloadTaskWithRequest:request];// NSURLSessionDownloadTask *_downloadTask; 成员变量 [_downloadTask resume];

苹果官方提供的Session还是非常给力的,使用也很方便。 让当前控制器成为当前session的代理,并且实现其中的代理方法,便可以对整个下载过程了如指掌

 #pragma mark - download代理方法

 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
NSLog(@"error- %@", error.localizedDescription);
} - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
CGFloat percent = (CGFloat)totalBytesWritten / totalBytesExpectedToWrite; dispatch_async(dispatch_get_main_queue(), ^{ _progress.progress = percent; // 进度
_progressLabel.text = [NSString stringWithFormat:@"当前:%.1fKb/s,进度:%.2f%%", bytesWritten / 1024.0f, percent * ];
});
} - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
NSLog(@"%@", location);
} - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{
NSLog(@"%lld", fileOffset);
}

AFNetWorking

下载使用示例代码:

 #pragma mark 下载
- (IBAction)download
{
// 1. 建立请求 _httpClient 是AFHTTPClient实例化出来的成员变量
NSURLRequest *request = [_httpClient requestWithMethod:@"GET" path:@"download/Objective-C2.0.zip" parameters:nil]; // 2. 操作
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request]; _downloadOperation = op; // 下载
// 指定文件保存路径,将文件保存在沙盒中
NSArray *docs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [docs[] stringByAppendingPathComponent:@"download.zip"]; op.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO]; // 设置下载进程块代码
/*
bytesRead 当前一次读取的字节数(100k)
totalBytesRead 已经下载的字节数(4.9M)
totalBytesExpectedToRead 文件总大小(5M)
*/
[op setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) { // 设置进度条的百分比
CGFloat precent = (CGFloat)totalBytesRead / totalBytesExpectedToRead;
NSLog(@"%f", precent); _progressView.progress = precent;
}]; // 设置下载完成操作
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { // 下载完成之后,解压缩文件
/*
参数1:要解结压缩的文件名及路径 path - > download.zip
参数2:要解压缩到的位置,目录 - > document目录
*/
[SSZipArchive unzipFileAtPath:path toDestination:docs[]]; // 解压缩之后,将原始的压缩包删除
// NSFileManager专门用于文件管理操作,可以删除,复制,移动文件等操作
// 也可以检查文件是否存在
[[NSFileManager defaultManager] removeItemAtPath:path error:nil]; // 下一步可以进行进一步处理,或者发送通知给用户。
NSLog(@"下载成功");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"下载失败");
}]; // 启动下载
[_httpClient.operationQueue addOperation:op];
}

上传示例代码

 #pragma mark - 文件上传
- (IBAction)uploadImage
{
/*
此段代码如果需要修改,可以调整的位置 1. 把upload.php改成网站开发人员告知的地址
2. 把file改成网站开发人员告知的字段名
*/
// 1. httpClient->url // 2. 上传请求POST
NSURLRequest *request = [_httpClient multipartFormRequestWithMethod:@"POST" path:@"upload.php" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
// 在此位置生成一个要上传的数据体
// form对应的是html文件中的表单
/*
参数
1. 要上传的[二进制数据]
2. 对应网站上[upload.php中]处理文件的[字段"file"]
3. 要保存在服务器上的[文件名]
4. 上传文件的[mimeType]
*/
UIImage *image = [UIImage imageNamed:@"头像1"];
NSData *data = UIImagePNGRepresentation(image); // 在网络开发中,上传文件时,是文件不允许被覆盖,文件重名
// 要解决此问题,
// 可以在上传时使用当前的系统事件作为文件名
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// 设置时间格式
formatter.dateFormat = @"yyyyMMddHHmmss";
NSString *str = [formatter stringFromDate:[NSDate date]];
NSString *fileName = [NSString stringWithFormat:@"%@.png", str]; [formData appendPartWithFileData:data name:@"file" fileName:fileName mimeType:@"image/png"];
}]; // 3. operation包装的urlconnetion
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request]; [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"上传完成");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"上传失败->%@", error);
}]; [_httpClient.operationQueue addOperation:op];
}

注意:AFN中数据不是线程安全的,如果使用暂停、继续功能会造成数据混乱,所以在使用AFN时,尽量不要暂停下载或者上传

AFN还可以用来判断网络状态

 - (IBAction)checkNetwork:(id)sender
{
// 1. AFNetwork 是根据是否能够连接到baseUrl来判断网络连接状态的
// 提示:最好使用门户网站来判断网络连接状态。
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"]; AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:url];
_httpClient = client; [_httpClient setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { // 之所以区分无线和3G主要是为了替用户省钱,省流量
// 如果应用程序占流量很大,一定要提示用户,或者提供专门的设置,仅在无线网络时使用!
switch (status) {
case AFNetworkReachabilityStatusReachableViaWiFi:
NSLog(@"无线网络");
break;
case AFNetworkReachabilityStatusReachableViaWWAN:
NSLog(@"3G网络");
break;
case AFNetworkReachabilityStatusNotReachable:
NSLog(@"未连接");
break;
case AFNetworkReachabilityStatusUnknown:
NSLog(@"未知错误");
break;
}
}];
}

ios开发之网络数据的下载与上传的更多相关文章

  1. iOS开发——网络Swift篇&NSURLSession加载数据、下载、上传文件

    NSURLSession加载数据.下载.上传文件   NSURLSession类支持三种类型的任务:加载数据.下载和上传.下面通过样例分别进行介绍.   1,使用Data Task加载数据 使用全局的 ...

  2. iOS开发进阶 - 使用shell脚本自动打包上传到fir.im上-b

    用fir.im测试已经好长时间了,感觉每次打包上传都很麻烦,想着是不是可以用脚本自动打包,在网上搜了一下确实有,下面总结一下如何使用脚本自动打包上传到fir.im,以及打包过程中遇到的问题和解决办法 ...

  3. Swift - 使用NSURLSession加载数据、下载、上传文件

    NSURLSession类支持三种类型的任务:加载数据.下载和上传.下面通过样例分别进行介绍. 1,使用Data Task加载数据 使用全局的sharedSession()和dataTaskWithR ...

  4. iOS开发-AFNetworking参数和多文件同时上传【多文件上传】

    1. 前言 在项目开发中,我们经常需要上传文件,例如:上传图片,上传各种文件,而有时也需要将参数和多个文件一起上传,不知道大家的项目中遇到了没有,我在最近的项目中,就需要这样的一个功能:同时上传参数. ...

  5. iOS开发之网络数据解析(二)--XML解析简介

    前言:本篇随笔介绍的是XML解析. 正文: 1.XML解析方式有2两种: DOM:一次性将整个XML数据加载进内存进行解析,比较适合解析小文件 SAX:从根元素开始,按顺序一个元素一个元素往下解析,比 ...

  6. iOS开发之网络数据解析--GDataXML解析框架的使用

      前言:GDataXML是google基于C语言libxml2写的第三方框架,该源码文件就一个类,看其源码,基本使用了C语言的底层的很多lib编译库代码,所以刚导入使用,会报错提示需要设置导入需要的 ...

  7. iOS开发之网络数据解析--中文输出

    对于服务器返回的数据,解析之后直接打印,如果数据中原本有中文,可能会出现中文乱码的结果: 为了避免这个问题,可以通过类别来重写系统和打印相关的方法. 步骤: 1.新建文件名:Foundation+Lo ...

  8. iOS开发之网络数据解析(一)--JSON解析简介

    前言:对服务器请求之后,返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) 本篇随便先讲解JSON解析. 正文: 关于JSON: JSON是一种轻量级的数据格式,一般用于数据交互 ...

  9. iOS开发——网络篇——NSURLSession,下载、上传代理方法,利用NSURLSession断点下载,AFN基本使用,网络检测,NSURLConnection补充

    一.NSURLConnection补充 前面提到的NSURLConnection有些知识点需要补充 NSURLConnectionDataDelegate的代理方法有一下几个 - (void)conn ...

随机推荐

  1. UI1_HTTP下载

    // DataModel.h // UI1_HTTP下载 // // Created by zhangxueming on 15/7/17. // Copyright (c) 2015年 zhangx ...

  2. Java对象初始化详解(转)

    在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.本文试图对Java如何执行对象的初始化做一个详细深入地介绍(与对象初始化相同,类在被加载之后也是需要初始化的,本 ...

  3. 4月12日学习笔记——jQuery事件

    下面是在 jQuery 中最常使用的 bind()方法举例:$("#testDiv4").bind("click", showMsg); 我们为 id 是 te ...

  4. bzoj2395[Balkan 2011]Timeismoney最小乘积生成树

    所谓最小乘积生成树,即对于一个无向连通图的每一条边均有两个权值xi,yi,在图中找一颗生成树,使得Σxi*Σyi取最小值. 直接处理问题较为棘手,但每条边的权值可以描述为一个二元组(xi,yi),这也 ...

  5. 试写Python内建函数range()

    还没查阅源码,先试着练手 class my_range(object): def __init__(self, *args): if not args: raise TypeError, 'range ...

  6. Mentor PADS 9.5下载安装及破解指南

    Pads,是一款用于设计.模拟电子线路及设计电路板的电脑软件,原由Innoveda公司开发,其后改名为PowerPCB,在2002年4月Innoveda被Mentor Graphics收购,近年再次改 ...

  7. Linux ThunderBird Exchange 过期

    在Linux上只用Web版处理邮件,就是因为找不到太好的能支持Exchange的邮件客户端.在网上无意中发现了ExQuilla这个Thunderbird的插件,试用了一下还是不错的,很方便,不过只能免 ...

  8. 惠普M1005打印机无法自动进纸的问题

    惠普M1005打印机无法自动进纸的问题 问题起因 其实我也不太清楚是什么起因,前一天用的好好的惠普M1005打印机,在打印时没有直接打印,会弹出一个提示对话框,同时打印机显示屏上显示“load tra ...

  9. Android 多国语言

    参考android 开发文档,  ISO 639-1  ISO 3166-1-alpha-2 关于中国的: 中国其他地区: https://en.wikipedia.org/wiki/ISO_3166 ...

  10. Crusher Django 学习笔记4 使用Model

    http://crusher-milling.blogspot.com/2013/09/crusher-django-tutorial4-using-basic.html 顺便学习一下FQ Crush ...