Upload file method for IOS network request nsurlsession

Source: Internet
Author: User

The theoretical basis of this article is mainly related to HTTP network communication protocol. To focus, you can ignore the TCP/IP protocol first, which is to focus on the structure of HTTP requests and responses. HTTP Complete principle content this is skipped. Only briefly mention the relevant content here. The text involved in the design of source code can be obtained here https://github.com/wuqingjian2015/uploadHelper, interested parties can go to see.

What is HTTP for?

Consider the following application process first:

    1. Initiates a request from the client to the server side .
    2. Server-side processing requests .
    3. A response is sent from the server side .

Then, if you apply the above procedure to achieve the ability to upload files, you need to do several things:

    1. The file to be uploaded needs to be bundled in this request.
    2. The server can understand the request, and make relevant processing: If you can extract the contents of the file, stored in a file directory, if you can extract some of the instructions, call the relevant instruction handlers.
    3. The server sends a response, and the client should be able to understand the response content.

The HTTP protocol solves these problems. It defines the structure of the request body and the response body. As long as the client or server complies with this standard, it communicates with any application that adheres to this standard.

If you want to observe the HTTP standard of the request body and the response body "long" what kind of, you can use some grab bag tool. I used Wireshark and Charles. If you are a Web application, you can press the F12 key on IE to bring up the web tab of the development tool window.

Here, we only focus on the request, understanding that the response statuscode is 200 normal.

For the request, because iOS automatically sets the other content if we don't set it. The following is only a discussion of

    1. The destination address to upload to
    2. Content-type in the request header
    3. and the contents of the request body

How do I set the destination address? when you create a nsurlrequest, you specify the URL. Such as

Nsmutableurlrequest *request = [[Nsmutableurlrequest alloc] InitWithURL:self.targetURL];

Next, we need to set the value of Content-type to: Multipart/form-data, and also set the value of boundary, the boundary will be used when setting the request body. So far, we've got some code like this:

-(Nsurlrequest *) Createrequestheader

{

Nsmutableurlrequest *request = [[Nsmutableurlrequest alloc] InitWithURL:self.targetURL]; Specify Destination Address

Creating HTTP Header Request Header content

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;

}

Now let's see how the request body is set. In iOS, it is specified by the Nsurlrequest.httpbody property, which is the NSData type. Remember: this has a fixed format that must be correct, otherwise the server side cannot get the correct content. And this problem cannot be reflected in the clutch tool. As follows:

Format:

Beginboundary

Content-disposition:form-data; Name= "< server-side need to know the name >"; Filename= "< server-side this pass-through file name >"
Content-type:application/zip--Choose a different value depending on the file type

< empty line >

< binary data >

Endboundary

Example:

----KenApp299912318
Content-disposition:form-data; Name= "< server-side need to know the name >"; Filename= "< server-side this pass-through file name >"
Content-type:application/zip--Choose a different value depending on the file type

< empty line >

< binary data >

----kenapp299912318--

There is the truth in code:

-(nsdata*) Createdataforrequesthttpbodyforsource

{

nsmutablestring *bodyhead = [[Nsmutablestring alloc] init];

Nsmutabledata *data = [[Nsmutabledata alloc] init];

NSString *filename = [Self.sourceurl lastpathcomponent];

NSString *[email protected] "uploadfile";

NSData *filecontent = [NSData DataWithContentsOfURL:self.sourceURL];

Create HTTP body Request Body content

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

(Blank line)

[Bodyhead appendformat:@ "content-type:application/zip\r\n\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 the request body. How do you use these results?

If you use nsurlconnection, we need to set both in the same nsurlrequest.

Call factory method Again [nsurlconnection connectionwithrequest:delegate:];

If you are using Uploadtask in nsurlsession, you need to set the request header (Requestwithheader below) in Nsurlrequest and set the request body in NSData (Requesthttpbody below). The code examples are as follows, where 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.ephemeralsession uploadtaskwithrequest:[uploadhelper RequestWithHeader] Fromdata:[uploadhelper Requesthttpbody] completionhandler:^ (NSData * _nullable data, Nsurlresponse * _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];

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

At this point, the client's design is basically complete. In order to see the uploaded files on the server side, we need to build a server environment. I personally implemented a Python-based rest micro-server that takes the files from the request and saves them to a local directory in a POST request that processes to archflow/upload. This is my software architecture used in the tool server, based on the temporary upload file function.

Functional testing:

In the process of server startup, execute the above client code, you can see the files are copied to the target directory.

Precautions:

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

The rest is patient debugging. Good luck!

Upload file method for IOS network request nsurlsession

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.