NSURLConnection provides a simple interface to create and cancel a connection, and supports a collection of proxy methods to provide a response to the connection and control the connection in many ways. The methods of this class fall into five broad categories: URL loading, cache management, authentication and certificates, cookie storage, and protocol support.

Creating a connection

NSURLConnection provides three ways to retrieve the contents of a URL: synchronously, asynchronously using completion processor blocks, and asynchronously using custom proxy objects.

Use synchronous request, the general is an exclusive thread running in the background thread, we can call sendSynchronousRequest: returningResponse: error: method to perform HTTP requests. This method returns when the request completes or when an error is returned.

If we don’t need to monitor the state of the request, but returned in the data to perform some operation, you can call sendAsynchronousRequest: queue: completionHandler: method to perform an asynchronous operations, which need to pass a block to handle the results.

We can also create a proxy object to handle asynchronous requests, in which case we need to implement the following methods: Connection: didReceiveResponse:, the connection: didReceiveData: and connection: didFailWithError: and the connectionDidFinishLoading:. These methods in NSURLConnectionDelegate, NSURLConnectionDownloadDelegate and NSURLConnectionDataDelegate defined in the agreement.

Listing 1 initializes a URL connection and implements the proxy method to handle the connection response, using the proxy object asynchronous request as an example

@interface Conn : NSObject

{

NSURLConnection *theConnection;

NSMutableData *receivedData;

}

@end

@implementation Conn

– (void)createConnection

{

// Create a request

NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:@”http://www.apple.com/”]

cachePolicy:NSURLRequestUseProtocolCachePolicy

TimeoutInterval: 60.0];

// Create NSMutableData to hold the received data

receivedData = [NSMutableData dataWithCapacity: 0];

// Use theRequest to create a connection and start loading data

// The transfer begins immediately after initWithRequest:delegate is called

/ / request in the connectionDidFinishLoading: or connection: didFailWithError: before the message is sent through a call to cancel to cancel

theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

if (! theConnection) {

// Release the receivedData object

receivedData = nil;

// Notify the user of a connection failure

}

}

/ / when the server provides the effective data to create NSURLResponse objects, the agent will receive the connection: didReceiveResponse: message.

// The proxy method checks the NSURLResponse object and verifies the content-Type, MIME type, file name, and other metadata of the data.

/ / it is important to note that for a single connection, we may meet many times received the connection: didReceiveResponse: message; This situation happened when

// The response is multiple MIME encodings. Each agent receives the connection: didReceiveResponse: when should reset progress indicator

// Discard the previously received data.

– (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

{

[receivedData setLength:0];

}

/ / agent regularly receives the connection: didReceiveData: message, the message is used for receiving server data returned by the entity. This method is responsible for storing data.

/ / we can also use this method to provide progress information, in this case, we need the connection: didReceiveResponse: method

// Call the expectedContentLength method of the response object to get the total length of the data.

– (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

[receivedData appendData:data];

}

/ / if there is error in the process of data transmission, the agent will receive the connection: didFailWithError: message. The error parameter gives error information.

/ / in the agent received the connection: didFailWithError: news, it will no longer receive the specified connection broker message.

– (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

{

theConnection = nil;

receivedData = nil;

NSLog(@”Connection failed! Error – %@ %@”, [error localizedDescription], [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);

}

/ / if successful access to the server returns all the data, the agent will receive the connectionDidFinishLoading: message.

– (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

NSLog(@”Succeeded! Receive %lu bytes of data(unsigned long)”,[receivedData length]);

theConnection = nil;

receivedData = nil;

}

@end

Make a POST request

We can make an HTTP or HTTPS POST request just like any other URL request. The main difference is that we must first be configured NSMutableURLRequest objects, and it is passed as a parameter to initWithRequest: delegate: method.

In addition, we need to construct the requested body data. It can be handled in three ways

For uploading short memory data, we need to URL-encode the existing data block

If the file is uploaded from disk, the setHTTPBodyStream: method is called to tell NSMutableURLRequest to read from an NSInputStream and use the resulting data as the body content

For large pieces of data, call CFStreamCreateBoundPair to create a pair of stream objects, and then call the setHTTPBodyStream: method to tell NSMutableURLRequest to use one of these stream objects as the source of the body content. You can send a small piece of data at a time by writing it to another stream.

When uploading data to a compatible server, the URL loading system also supports a 100 (continue) status code, allowing an upload operation to continue in the event of an authentication error or other failure. To enable this operation, set the expect header of the request object to 100-continue.

Listing 2 shows how to configure an NSMutableURLRequest object for a POST request

– (void)setRequestForPost

{

// For application/x-www-form-urlencoded body data, form field parameters are separated by am&,

NSString *bodyData = @”name=Jane+Doe&address=123+Main+St”;

NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@”https://www.apple.com”]];

// Set content-type to Application /x-www-form-urlencoded

[postRequest setValue:@”application/x-www-form-urlencoded” forHTTPHeaderField:@”Content-Type”];

// Specify POST as the request method

[postRequest setHTTPMethod:@”POST”];

[postRequest setHTTPBody:[NSData dataWithBytes:[bodyData UTF8String] length:strlen([bodyData UTF8String])]];

// Initialize the NSURLConnection and proceed as described in

// Retrieving the Contents of a URL

}

Use blocks to receive data

Class provides methods NSURLConnection sendAsynchronousRequest: queue: completionHandler:, this method can be initiated by the abnormal way to server request, and return the data error or/block when the timeout to deal with. This method requires a request object, a block to complete processing, and a queue to run the block. When the request completes or an error occurs, the URL loading system calls this block to process the resulting data or error message.

If the request succeeds, an NSData object and an NSURLResponse object are passed to the block. If this fails, an NSError object is passed.

There are two limitations to this approach

Only minimal support is provided for requests that require authentication.

There is no way to modify the default behavior of response caching and server-side redirection