- Constructing an XML Document
- Transmitting an XML Document
- Deconstructing an XML Document
- Conclusion
Transmitting an XML Document
Transmitting the XML document to a server is a matter of opening an NSURLConnection to the server and posting the document:
- (void)transmitXMLRequest:(NSData *)data { NSURL *webServiceURL = [NSURL URLWithString:@"http://test.com/xmlResponder"]; NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:webServiceURL]; [urlRequest setHTTPMethod:@"POST"]; [urlRequest setValue:@"text/xml" forHTTPHeaderField:@"Content-type"]; [urlRequest setHTTPBody:data]; NSURLConnection *connectionResponse = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self]; if (!connectionResponse) { NSLog(@"Failed to submit request"); } else { NSLog(@"Request submitted"); responseData = [[NSMutableData alloc] init]; } }
In the first line I constructed an NSURL object which points to the Web service I will be posting against. I then constructed an NSMutableURLRequest against that URL and set it up as an HTTP POST request. I then set the NSData representation of the XML document as the body of the request. Finally, I constructed an NSURLConnection with the NSMutableURLRequest. The construction of the NSURLConnection is what actually kicks off the post to the server.
Assuming that the NSURLConnection initializes properly, I then initialized the receiving NSMutableData object. As the data is returned from the server it will be stored in this object until the receiving portion of the flow is complete.
In the construction of the NSURLConnection I was required to pass in a delegate because NSURLConnection actually spins off a thread that will block and wait for a response from the server. As the response comes in from the server, the NSURLConnection calls one of several methods on the delegate. The methods are as follows:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
This method is normally called only once during the life of the NSURLConnection. It is normally called at the start of the receipt of data. However, if the server does any URL redirects, it is possible that this method will be called multiple times. Therefore, whenever this method is called, the data received from the server should be reset as follows:
[responseData setLength:0];
This will ensure that the data stream is not corrupted by any URL redirects.
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
This method will be called multiple times by the NSURLConnection. Whenever a block of data is received from the server, the data is passed to this method. The data being passed in should just be appended to the end of the NSMutableData object:
[responseData appendData:data];
The exact side of each of these pieces is dependent on a great many factors that are outside the scope of this article. It is a safe assumption that this method will be called many times during the life of the NSURLConnection and therefore should be fairly efficient. It would not be wise to put any lengthy processing in this portion of the flow.
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
If at any time during the receipt of data there is an unrecoverable error, this method will be called. This method is a termination of the NSURLConnection. At this point, the NSURLConnection and the NSMutableData objects should be released and the error processed:
NSLog(@"Error receiving response: %@", error); [connection release]; [responseData release];
In this example I simply reported the error to the console and released the objects. In a production application it would be wise to report the error to the user.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
This method is called at the successful conclusion of the transmission. After this method is called, all the data has been received and the NSURLConnection can be safely closed.
[connection release]; [self deconstructXMLResponse:responseData]; [responseData release];
In this example I simply released the NSURLConnection and passed the received data to the next step. After that was completed, I released the NSMutableData object.
The NSURLConnection object makes it very simple to talk to any HTTP Server on the Internet, and either retrieve data or post data to the server. Because the NSURLConnection handles all the messy details of threading for me, my application can remain responsive during the transmission without having to work with threads myself.