iOS开发之网络编程--5、NSURLSessionUploadTask+NSURLSessionDataDelegate代理上传

前言:关于NSURLSession的主要内容快到尾声了,这里就讲讲文件上传。关于文件上传当然就要使用NSURLSessionUploadTask,这里直接讲解常用的会和代理NSURLSessionDataDelegate一起搭配实现文件上传功能。另外,下面使用的文件上传思路是和NSURLConnection中本人之前的随笔《iOS开发之网络编程--使用NSURLConnection实现文件上传》提到的上传思路是一样的,都是要将请求信息拼接起来,然后传入到请求里进行上传。这个拼接过程是必要的,但是也是比较繁琐的,下面我就不过多讲解细节了。另外使用代理也比较简单,所以就直接展示全部源码。

 

#import "ViewController.h"
#define kBoundary @"----WebKitFormBoundary0IQAt0HA7oxwIx3f"
#define KNewLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]

@interface ViewController ()<NSURLSessionDataDelegate>

@end

@implementation ViewController

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"------");
    //1.创建会话对象,设置代理
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    //2.创建请求对象
    NSURL *url =[NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    //2.1 修改请求方法
    request.HTTPMethod = @"POST";

    //2.2 设置请求头
    NSString *header = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",kBoundary];
    [request setValue:header forHTTPHeaderField:@"Content-Type"];

    //3.创建上传task
    /*
     第一个参数:请求对象
     第二个参数:要上传文件的参数(二进制数据
     第三个参数:completionHandler
        data:服务器返回的结果(响应体信息)
        response:响应头
     */
   NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[self getBodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

       //5.解析结果
       NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
    }];

    //4.执行任务
    [uploadTask resume];

}

-(NSData *)getBodyData
{
    //5.拼接数据
    NSMutableData *fileData = [NSMutableData data];

    //5.1 拼接文件参数
    /*
     --分隔符
     Content-Disposition: form-data; name="file"; filename="Snip20151228_572.png"
     Content-Type: image/png
     空行
     文件二进制数据
     */
    [fileData appendData:[[NSString stringWithFormat:@"--%@",kBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [fileData appendData:KNewLine];
    // name="file":参数,是固定的
    // filename:文件上传到服务器以什么名字来保存,随便
    [fileData appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"Snip20151228_572.png\"" dataUsingEncoding:NSUTF8StringEncoding]];

    [fileData appendData:KNewLine];
    //Content-Type:要上传的文件的类型 (MIMEType)
    [fileData appendData: [@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
    [fileData appendData:KNewLine];
    [fileData appendData:KNewLine];

    UIImage *image = [UIImage imageNamed:@"Snip20151229_713"];
    NSData *imageData = UIImagePNGRepresentation(image);
    [fileData appendData:imageData];
    [fileData appendData:KNewLine];

    //5.2 拼接非文件参数
    /*
     --分隔符
     Content-Disposition: form-data; name="username"
     空行
     非文件参数的二进制数据
     */
    [fileData appendData:[[NSString stringWithFormat:@"--%@",kBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [fileData appendData:KNewLine];

    //username:同file 是服务器规定
    [fileData appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
    [fileData appendData:KNewLine];
    [fileData appendData:KNewLine];
    [fileData appendData:[@"dashen9" dataUsingEncoding:NSUTF8StringEncoding]];
    [fileData appendData:KNewLine];

    //5.3 拼接结尾标识
    /*
     --分隔符--
     */
    [fileData appendData:[[NSString stringWithFormat:@"--%@--",kBoundary] dataUsingEncoding:NSUTF8StringEncoding]];

    return fileData;
}

#pragma mark ----------------------
#pragma mark NSURLSessionDataDelegate
/*
 第一个参数:bytesSent本次发送数据的大小
 第二个参数:totalBytesSent一共发送了多少数据
 第三个参数:totalBytesExpectedToSend文件的总大小
 */
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
{
    NSLog(@"已经上传了%f的数据",1.0 * totalBytesSent/totalBytesExpectedToSend );
}
@end
时间: 2024-08-02 18:02:50

iOS开发之网络编程--5、NSURLSessionUploadTask+NSURLSessionDataDelegate代理上传的相关文章

iOS开发之网络编程--使用NSURLConnection实现文件上传

前言:使用NSURLConnection实现文件上传有点繁琐.    本文并没有介绍使用第三方框架上传文件.   正文: 这里先提供用于编码测试的接口:http://120.25.226.186:32812  点击进去你会发现到下面: 最好该链接用Google浏览器打开,因为Google浏览器开启开发者模式用起来方便些. 然后可以选择一个图片,然后点击上传,链接就会变成:http://120.25.226.186:32812/upload ,这个链接后面编码上传文件就要用到. 浏览器呈现的请求信

iOS开发之网络编程--4、NSURLSessionDataTask实现文件下载(离线断点续传下载) &lt;进度值显示优化&gt;

前言:根据前篇<iOS开发之网络编程--2.NSURLSessionDownloadTask文件下载>或者<iOS开发之网络编程--3.NSURLSessionDataTask实现文件下载(离线断点续传下载)>,都遗留了一个细节未处理的问题,那就是在离线断点下载的过程中,当应用程序重新启动之后,进度条的进度值默认没有设置为之前已经下载的进度,根据基本公式"当前进度值 = 已经下载的数据长度 ÷ 最终下载完的数据总长度",已经下载的数据长度可以由沙盒中已经下载的那

iOS开发之网络编程--3、NSURLSessionDataTask实现文件下载(离线断点续传下载)

前言:使用NSURLSessionDownloadTask满足不这个需要离线断点续传的下载需求,所以这里就需要使用NSURLSessionDataTask的代理方法来处理下载大文件,并且实现离线断点续传. 关于NSURLSessionDownloadTask的知识,可以请读者阅读本人的前篇:<iOS开发之网络编程--2.NSURLSessionDownloadTask文件下载>. 另外呢,因为NSURLSessionDownloadTask和NSURLSessionDataTask分别都是NS

iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载

前言:iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载是在前篇iOS开发之网络编程--使用NSURLConnection实现大文件下载的基础上进行    断点续传的设置.关于iOS开发之网络编程--使用NSURLConnection实现大文件下载的细节这里当然就不会再累述的啦.   断点续传的原理:    每次在向服务器请求下载数据的同时,要告诉服务器从整个下载文件的数据流的某个还未下载的位置开始下载,然后服务器就返回从那个位置开始的数据流.    图片示意图:

iOS开发之网络编程--使用NSURLConnection实现大文件下载

主要思路(实现下载数据分段写入缓存中) 1.使用NSURLConnectionDataDelegate以及代理方法. 2.在成功获取响应的代理方法中,获得沙盒全路径,并在该路径下创建空文件和文件句柄. 3.在获取data的代理方法中,先设置句柄在沙盒全路径文件末尾,然后通过句柄写入data数据. 4.在文件下载完的代理方法中,关闭句柄同时设置句柄引用为nil释放句柄和指针. 使用句柄的思路图(红色的箭头表示句柄,灰色的箭头表示移动的路径): 代码关键词: 类:NSFileHandle的方法 1.

ios开发之网络编程

上周末本应早写这个网络和MapKit的. 由于周六朋友聚会,周日送一朋友回远方,吃吃喝喝的就忘掉了. 网络编程基本是移动互联这块中必须掌握的编程技巧.由于我买的的小柚子书上没有这块, 最近刚买的开发秘籍那本上的关于网络链接这块,太抽象了. 首先吐槽一下这本书,细节描述的还是不错的.但是不合适做入门~ 然后在网络上搜索关于ios的网络编程基本就首页全是讲的同一篇文章,被转烂了. 找了半天没找到源文出处. 可以参考的一个地址:http://www.cocoachina.com/bbs/read.ph

IOS开发之网络编程--文件压缩和解压缩

前言: QQ表情包就用到了解压缩,从网络下载的那么多表情文件格式并不是一个一个图片文件,而是多个图片压缩而成的表情压缩包.下面介绍的是iOS开发中会用到的压缩和解压缩的第三方框架的使用. 注意: 这个第三方框架代码文件夹是SSZipArchive,使用cocoapods搜索也是搜索SSZipArchive.但是如果你在github上直接搜索ZipArchive,搜到点赞数最多,维护频繁的ZipArchive库,然后下载代码,其实就是这个SSZipArchive. 第三方框架github网址:ht

iOS开发之网络编程--6、NSURLSessionConfiguration笔记

NSURLSessionConfiguration对象用于初始化NSURLSession对象. 展开请求级别中与NSMutableURLRequest相关的可供选择的方案,我们可以看到NSURLSessionConfiguration对于会话如何产生请求,提供了相当多的控制和灵活性.从网络访问性能,到cookie,安全性,缓存策略,自定义协议,启动事件设置,以及用于移动设备优化的几个新属性,你会发现你一直在寻找的,正是NSURLSessionConfiguration. 会话在初始化时复制它们的

iOS开发之网络编程--中文转码

前言: 在GET请求或者是POST请求,请求上传的参数如果含有中文,可能会导致请求失败. 所以要对存储了URL地址的NSString对象进行中文转码,然后将这个NSString对象传递给URL.   正文: 首先是本地服务器的账户和密码先曝光一下下哦,我有JavaWeb的简易程序,用Eclipse可以运行,嘻嘻,下面是JavaWeb的程序源码和效果截图:  好,回到客户端,也就是我们的IOS前端,来看看我写的网络请求: 下面是GET请求,GET请求要讲URL的NSString对象进行中文转码: