File upload of NSURLSession on the network

Keywords: Session Programming

Some APPs need to store pictures, videos, documents and other information. App developers want users to be able to access information saved by users on any device, which requires the support of the server. How to upload data by APP is the problem to be solved in this article.

  • Introduction to NSURLSession Upload Task
  • Upload Task with NSURLSession
  • summary

Introduction to NSURLSession Upload Task

NSURLSession Upload Task supports three types of upload tasks: NSData objects, files and streams.
· If your data is all in memory, it's better to use NSData objects.
· If your data is uploaded as a file, it does not take up much memory.
· If you need to upload production data, use data streaming.

Regardless of how to upload data and obtain data upload information (progress, etc.), the proxy method should be implemented.

/**
 * @param (int64_t)bytesSent How much data are uploaded per second
 * @param (int64_t)totalBytesSent How many data have been uploaded
 * (int64_t)totalBytesExpectedToSend Total size of data to be uploaded
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend;

Upload Task with NSURLSession

There are three ways to upload files using NSURLSession Upload Task:

  1. NSData object upload
    -(NSURLSessionUploadTask )uploadTaskWithRequest:(NSURLRequest )request fromData:(NSData *)bodyData;
  2. File upload
    -(NSURLSessionUploadTask )uploadTaskWithRequest:(NSURLRequest )request fromFile:(NSURL *)fileURL;
  3. Streaming upload
    -(NSURLSessionUploadTask )uploadTaskWithStreamedRequest:(NSURLRequest )request;
******************************************************************************     // Loading files from disk to memory and uploading them as NSData data takes up a lot of memory.
     // The path to get the file
    NSURL *textFileURL = [NSURL fileURLWithPath:@"/path/UsingNSURLSession.htm"];
    //Load into memory as an NSData object
    NSData *data = [NSData dataWithContentsOfURL:textFileURL];

    // Set up the uploaded server address and the Request object.
    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"];

    // Create session types
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:[[UploadTaskDelegate alloc] init] delegateQueue:[NSOperationQueue mainQueue]];

    // Creating Upload Tasks Using NSData Objects
    NSURLSessionUploadTask *uploadTask = [[self defaultSession] uploadTaskWithRequest:mutableRequest fromData:data];
    [uploadTask resume];******************************************************************************    //Note that uploading as NSData is different from uploading as a file. As a file upload, we don't need to load it into memory. The NSDATA upload above requires manual loading into memory. So it doesn't take up much memory.
    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";

    // Creating Upload Tasks Using File Paths
    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];

/******************************************************************************    //Paths to be uploaded
    NSURL *textFileURL = [NSURL fileURLWithPath:@"/Users/ag/Desktop/UsingNSURLSession.htm"];

    //Configuration requester
    //Setting the server's URL
    NSURL *url = [NSURL URLWithString:@"https://www.example.com/"];
    NSMutableURLRequest *mutableRequest = [NSMutableURLRequest requestWithURL:url];
    //Setting Request Method
    mutableRequest.HTTPMethod = @"POST";
    //Upload data as a stream. Note that NSInputStream *HTTPBodyStream and NSData *HTTPBody are mutually exclusive and should not be set at the same time.
    mutableRequest.HTTPBodyStream = [NSInputStream inputStreamWithFileAtPath:textFileURL.path];
    [mutableRequest setValue:@"text/plain" forHTTPHeaderField:@"Content-Type"];
    //How much information is needed.
    [mutableRequest setValue:[NSString stringWithFormat:@"%lld", [NSData dataWithContentsOfURL:textFileURL].length] forHTTPHeaderField:@"Content-Length"];

    //Flow Creation Upload Task
    NSURLSessionUploadTask *uploadTask = [[self defaultSession] uploadTaskWithStreamedRequest:mutableRequest];
    [uploadTask resume];******************************************************************************/

//Agent method
/**
 * Getting the uploaded progress information can help us realize the progress bar reasonably.
 * @param (int64_t)bytesSent How much data are uploaded per second
 * @param (int64_t)totalBytesSent How many data have been uploaded
 * (int64_t)totalBytesExpectedToSend Total size of data to be uploaded
 */
- (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);
}


We clearly see the 111KB file, the uploaded information.

summary

Upload tasks can be uploaded in three ways. If your file is small and does not occupy much memory, you can use NSData to create upload tasks. Otherwise, use files to create upload tasks. If you want to upload production data, use streaming.

Reference material

Official document: URL Session Programming Guide

Posted by buildernaut1 on Wed, 22 May 2019 12:11:13 -0700