NSURLSession/NSURLConnection File Upload method, nsurlsession upload Image

Source: Internet
Author: User
Tags temporary file upload

NSURLSession/NSURLConnection File Upload method, nsurlsession upload Image

The best way to learn is understanding + understanding.

The theoretical basis of this article is mainly related to the HTTP network communication protocol. In order to concentrate, you can ignore the TCP/IP protocol, that is, focus only on the HTTP request and response structure. The complete principles of HTTP are omitted. Here, we will only mention the relevant content. The design Source Code involved in this article can be obtained here at https://github.com/wuqingjian2015/uploadhelper. you can check it if you are interested.

 

What is HTTP used?

Consider the following application process:

If you use the above process to upload files, you need:

The HTTP protocol solves these problems. It defines the Request body structure and response body structure. As long as the client or server complies with this standard, it can communicate with any application that complies with this standard.

If you want to observe what the HTTP-compliant request bodies and response bodies are "long", you can use some packet capture tools. I used Wireshark and Charles. For Web applications, press F12 on IE to bring up the network Tab of the development tool window.

Here, we only pay attention to the request and understand that the response StatusCode is 200, which indicates that it is normal.

For requests, because iOS will automatically set other content, if we do not set it. Here we will only discuss

How do I set the target address?Specify the URL when creating an NSURLRequest. For example,

NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL: self.tar getURL];

Next, we needSet the Content-Type ValueIs: multipart/form-data, and boundary value is also set, this boundary will be used when setting the Request body. So far, we have obtained such code:

-(NSURLRequest *) createRequestHeader

{

NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL: self.tar getURL]; // specify the target address

// Create an http header

// Content-Type: = multipart/form-data; boundary = --------------- 827292 (any)

// Content-Length: = (file Length)

NSString * contentType = [NSString stringWithFormat: @ "multipart/form-data; boundary = % @", self. boundary];

[Request setValue: contentType forHTTPHeaderField: @ "Content-Type"]; // set Content-Type

[Request setHTTPMethod: @ "post"]; // set Method to POST

Return request;

}

Next, let's see how to set the Request body. In iOS, it is specified by the NSURLRequest. HTTPBody attribute, which is of the NSData type.Remember:There is a fixed format. The format must be correct. Otherwise, the server cannot obtain the correct content. This problem cannot be reflected in the packet capture tool. As follows:

Format:

BeginBoundary

Content-Disposition: form-data; name = "<name required by the server>"; filename = "<name of the uploaded file on the server>"
Content-Type: application/zip -- select different values based on different file types

<Blank line>

<Binary data>

EndBoundary

Example:

---- KenApp299912318
Content-Disposition: form-data; name = "<name required by the server>"; filename = "<name of the uploaded file on the server>"
Content-Type: application/zip -- select different values based on different file types

<Blank line>

<Binary data>

---- KenApp299912318 --

Code has the truth:

-(NSData *) createDataForRequestHTTPBodyForSource

{

NSMutableString * bodyHead = [[NSMutableString alloc] init];

NSMutableData * data = [NSMutableData alloc] init];

NSString * fileName = [self. sourceURL lastPathComponent];

NSString * name = @ "uploadFile ";

NSData * fileContent = [NSData dataWithContentsOfURL: self. sourceURL];

// Create the http body request body content

// The first line: -- 827292

[BodyHead appendString: self. beginBoundary];

// [Body appendFormat: @ "--------------------"]

// Content-Disposition: form-data; name = "uploadFile"; filename = "xxxx. ext"

[BodyHead appendFormat: @ "Content-Disposition: form-data; name = \" % @ \ "; filename = \" % @ \ "\ r \ n", name, fileName];

// Content-Type: application/x-zip-compressed

// (Empty rows)

[BodyHead appendFormat: @ "Content-Type: application/zip \ r \ n"];

// (Binary data)

[Data appendData: [bodyHead dataUsingEncoding: NSUTF8StringEncoding];

[Data appendData: fileContent];

// Last line: 827292 --

[Data appendData: [self. endBoundary dataUsingEncoding: NSUTF8StringEncoding];

Return data;

}

So far, we know how to set the request header and request body. How can we use these results?

If NSURLConnection is used, we need to set the two in the same NSURLRequest.

Call factory method again[NSURLConnection connectionWithRequest: delegate:];

If you use uploadTask in NSURLSession, you need to set the Request Header (the following requestWithHeader) in NSURLRequest, and set the Request body (the following requestHTTPBody) in NSData ). The code example is as follows. SSUploadHelper encapsulates the process mentioned above.

//// // Example ///// ///////////////////

SSUploadHelper * uploadHelper = [[SSUploadHelper alloc] initWithTarget: [NSURL URLWithString: @ "http: // 192.168.31.172: 5012/ArchFlow/upload"] forSource: self. downloadedLocation];

NSURLSessionUploadTask * uploadTask = [self. response handler: [uploadHelper requestWithHeader] fromData: [uploadHelper requestHTTPBody] completionHandler: ^ (NSData * _ Nullable data, Handler * _ Nullable response, NSError * _ Nullable error ){

NSLog (@ "Got response % @ with error % @. \ n", response, error );

NSLog (@ "DATA: \ n % @ \ nEND DATA \ n ",

[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]);

}];

[UploadTask resume];

//////////////////////////////////

So far, the client design is basically complete. To view the uploaded files on the server side, we need to build a server environment. I personally implemented a Python-based REST microserver. In the POST request for processing ArchFlow/upload, I obtained the file from the request and saved it to the local directory. This is the tool server I used in the software architecture. On this basis, the temporary file upload function is implemented.

// Function test:

When the server is started, run the above client code and you can see that the file is copied to the target directory.

Note:

The boundary format is worth noting that the boundary specified in the request header must be in the Request body.

The rest is patience debugging. Good Luck!

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.