Apart from few games and static utility applications, most of the iPhone applications communicate with the remote server. As long as the payload is limited to few kilobytes and generation time of payload is low, traditional communication methods give acceptable performance.
Generally, developers send data to the server after entire data is collected from the end user. Better approach is to send the data into chunks to the server. Data sent into chunks can be regenerated as a single payload on receiver end or it can be processed into chunk format also. This mode of communication is known as Chunked Transfer. Significant performance gain can be achieved when data is streamed to the server, a heavy payload needs to be uploaded to the server and when data generation time on client side is more.
There are no major changes required on server end to take the advantage of chunked transfer. Chunked transfer is a data transfer technique of HTTP version 1.1. If the http header contains the value as “chunked” for key “Transfer-Encoding”, it will ignore the “Content-Length”. It informs HTTP that the size of the payload is not known yet. Once the end chunk is identified, the data transfer is terminated.
Lets understand, the code changes needs to make on iOS side to take the advantage of chunked transfer. To make it simple consider an example of uploading an audio stream (produced by audio unit) to the server in chunked mode.
Below code creates a dummy URL where audio-streamed data will be uploaded.
Code Fragment 1
- Add “Transfer-Encoding” as “chunked” in the HTTP header fields.
Refer the below code segment.
Code Fragment 2
- A bounded pair of stream is created.
- The bounded pair can transfer data from read stream to write stream. It allows to bound input stream to URL request.
- Simultaneously data written to output stream, which is generated by audio unit, will be automatically transferred to input stream.
- To write the data to output stream, it should be in open state.
- Scheduling of output stream with run loop will make sure that the delegate will not suffer with blocking when there is no space left for stream to accept the data.
Note: Use the run loop of a thread, which is responsible for streaming. It is hazardous to access scheduled stream from a different thread which is not owning the run loop.
Code Fragment 3
The input stream should be assigned to URL request. Refer Code Fragment 3 to achieve it.
Now it’s a time to create connection object with above created URL request. The connection object should also get scheduled with run loop. The reason is now known to us..!! Refer Code Fragment 4 to achieve it.
Code Fragment 4
Create a class and put down all the above code fragments as member function(s). Give the name of a class to ChunkTransfer.
Below code represents the implementation of audio recorder delegate, which produces audio data.
Code Fragment 5
- Above code fragment will get called when audio producer will produce audio data.
- It adds the object of audio data to queue.
- It tells ChunkTransfer object to send the data in chunk. If producer is not generating any data, it will close the stream and so connection.
Refer Code Fragment 6.
- It takes the data from data queue.
- This data will be written to output stream. Here input stream should be in open condition.
Code Fragment 6
Refer Code Fragment 7.
- It shows the mechanism to stop communication.
- Close the stream and remove it from run loop.
- Client will now wait until data will be received into NSConnection delegate.
- Set the variable ‘finished’ to TRUE inside appropriate connection delegate.
Code Fragment 7
Refer code fragment 8.
- It handles stream delegate.
- For now, we are more interested in output stream handling delegate. When output stream has available space to write data inside it, we should take advantage of sending chunk.
Code Fragment 8
The data is transferred to the server into chunks as data become available rather waiting for entire data to be available. It helps a lot to reduce the round trip time to server. Same strategy can be used while downloading the response also. In spite of collecting full response in the memory, we can start processing chunked data. In most cases, client can start parsing on storing these partial chunked data in one thread when the other thread is downloading response from remote server.
After all it matters much, how fast your application is responding..!