[iOS]网络之NSURLSession的文件上传

有些APP需要实现保存图片、视频、文档等信息。APP的开发者希望用户能够在任意设备上,获取用户保存的信息,这就需要服务器的支持了,APP如何上传数据,这就是这篇所要解决的问题。

  • NSURLSessionUploadTask 介绍
  • 使用NSURLSessionUploadTask进行上传
  • 总结

NSURLSessionUploadTask 介绍

NSURLSessionUploadTask支持三种任务类型中的上传任务类型,它支持三种上传类型:NSData对象、文件和流
· 如果你的数据全部在内存中,使用NSData对象好一点。
· 如果你的数据作为文件上传,这种方式不太占内存。
· 如果你需要边生产数据边上传,请使用数据流。

不管使用何种方式上传数据,获取数据上传信息(进度等),需实现代理方法:

/**
 * @param (int64_t)bytesSent 每秒上传多少数据
 * @param (int64_t)totalBytesSent 已经上传了多少数据
 * (int64_t)totalBytesExpectedToSend 需要上传数据的总共的大小
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend;

使用NSURLSessionUploadTask进行上传

使用NSURLSessionUploadTask进行文件上传,有三种方式:

  1. NSData对象上传
    -(NSURLSessionUploadTask )uploadTaskWithRequest:(NSURLRequest )request fromData:(NSData *)bodyData;
  2. 文件上传
    -(NSURLSessionUploadTask )uploadTaskWithRequest:(NSURLRequest )request fromFile:(NSURL *)fileURL;
  3. 流上传
    -(NSURLSessionUploadTask )uploadTaskWithStreamedRequest:(NSURLRequest )request;
******************************************************************************     // 从磁盘中加载文件到内存中,作为NSData数据进行上传,这种方式占用内存大。
     // 获取文件的路径
    NSURL *textFileURL = [NSURL fileURLWithPath:@"/path/UsingNSURLSession.htm"];
    //加载到内存中,作为NSData对象
    NSData *data = [NSData dataWithContentsOfURL:textFileURL];

    // 设置上传的服务器地址,设置Request对象。
    NSURL *url = [NSURL URLWithString:@"https://www.example.com/"];
    NSMutableURLRequest *mutableRequest = [NSMutableURLRequest requestWithURL:url];
    mutableRequest.HTTPMethod = @"POST";
    [mutableRequest setValue:[NSString stringWithFormat:@"%lld", data.length] forHTTPHeaderField:@"Content-Length"];
    [mutableRequest setValue:@"text/plain" forHTTPHeaderField:@"Content-Type"];

    // 创建会话类型
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:[[UploadTaskDelegate alloc] init] delegateQueue:[NSOperationQueue mainQueue]];

    // 利用NSData对象创建上传任务
    NSURLSessionUploadTask *uploadTask = [[self defaultSession] uploadTaskWithRequest:mutableRequest fromData:data];
    [uploadTask resume];******************************************************************************    //注意,作为NSData上传和作为文件上传是有区别的区别,作为文件上传,不需要我们加载到内存中。上面的NSData上传,是需要手动加载到内存中的。所以这种方式不怎么占内存。
    NSURL *textFileURL = [NSURL fileURLWithPath:@"/Users/ag/Desktop/UsingNSURLSession.htm"];
    NSURL *url = [NSURL URLWithString:@"https://www.example.com/"];
    NSMutableURLRequest *mutableRequest = [NSMutableURLRequest requestWithURL:url];
    mutableRequest.HTTPMethod = @"POST";

    // 利用文件路径创建上传任务
    NSURLSessionUploadTask *uploadTask = [[self defaultSession] uploadTaskWithRequest:mutableRequest fromFile:textFileURL];
    [uploadTask resume];******************************************************************************/

NSURL *textFileURL = [NSURL fileURLWithPath:@"/path/to/file.txt"];

NSURL *url = [NSURL URLWithString:@"https://www.example.com/"];
NSMutableURLRequest *mutableRequest = [NSMutableURLRequest requestWithURL:url];
mutableRequest.HTTPMethod = @"POST";
mutableRequest.HTTPBodyStream = [NSInputStream inputStreamWithFileAtPath:textFileURL.path];
[mutableRequest setValue:@"text/plain" forHTTPHeaderField:@"Content-Type"];
[mutableRequest setValue:[NSString stringWithFormat:@"%lld", data.length] forHTTPHeaderField:@"Content-Length"];

NSURLSessionUploadTask *uploadTask = [defaultSession uploadTaskWithStreamedRequest:mutableRequest];
[uploadTask resume];

/******************************************************************************    //待上传的路径
    NSURL *textFileURL = [NSURL fileURLWithPath:@"/Users/ag/Desktop/UsingNSURLSession.htm"];

    //配置请求体
    //设置服务器的URL
    NSURL *url = [NSURL URLWithString:@"https://www.example.com/"];
    NSMutableURLRequest *mutableRequest = [NSMutableURLRequest requestWithURL:url];
    //设置请求方法
    mutableRequest.HTTPMethod = @"POST";
    //将上传数据作为流进行上传,注意NSInputStream *HTTPBodyStream和NSData *HTTPBody是互斥的,不要同时设置。
    mutableRequest.HTTPBodyStream = [NSInputStream inputStreamWithFileAtPath:textFileURL.path];
    [mutableRequest setValue:@"text/plain" forHTTPHeaderField:@"Content-Type"];
    //需要告知内容有多大。
    [mutableRequest setValue:[NSString stringWithFormat:@"%lld", [NSData dataWithContentsOfURL:textFileURL].length] forHTTPHeaderField:@"Content-Length"];

    //流创建上传任务
    NSURLSessionUploadTask *uploadTask = [[self defaultSession] uploadTaskWithStreamedRequest:mutableRequest];
    [uploadTask resume];******************************************************************************/

//代理方法
/**
 * 获取上传的进度信息,可以帮组我们合理的实现进度条
 * @param (int64_t)bytesSent 每秒上传多少数据
 * @param (int64_t)totalBytesSent 已经上传了多少数据
 * (int64_t)totalBytesExpectedToSend 需要上传数据的总共的大小
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
{
        NSLog(@"Session %@ download task %@ wrote an additional %lld bytes (total %lld bytes) out of an expected %lld bytes.\n", session, task, bytesSent, totalBytesSent, totalBytesExpectedToSend);
}


我们很清楚的看到111KB的文件,上传的信息。

总结

上传任务可以分三种方式上传,如果你的文件小,不怎么占内存,可以使用NSData创建上传任务,否则请使用文件创建上传任务。如果想边生产数据边上传的话,请使用流。

参考资料

官方文档:URL Session Programming Guide

发布了16 篇原创文章 · 获赞 6 · 访问量 7627
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览