As a disclaimer I'd like to state that I'm fairly new to Objective-C and Cocoa. Currently I'm trying to write a basic application that can POST XML data to a particular endpoint. To achieve this, I've created a ServiceRouter class which uses NSURLConnection to post XML data to a particular URL.
The ServiceRouter class is intended as a base for subclasses which contain webservice-specific XML queries. In the example below, I subclass ServiceRouter to create a ServiceImplementation class.
When it's time to generate and POST the XML, I create an instance of the ServiceImplementation class like so:
[[ServiceImplementation alloc] createServiceSpecificXML];
This all seems to work fine. The issue is that Leaks reports a number of issues. Being fairly inexperienced, I'm not really sure where to start. For the most part, the NSURLConnection code is lifted from Apple's documentation.
Following basic memory management rules, I imagine I will have to release my ServiceImplementation instance at some point. What I'm confused about is how this should be handled given the asynchronous nature of NSURLConnection. Is this a candidate for autorelease?
I'm hoping that someone with more Objective-C/Cocoa experience can look things over and tell me if I'm moving in the right direction.
Here's the ServiceRouter class:
@interface ServiceRouter : NSObject {
NSMutableData *receivedData;
}
-(void)postXMLToURL:(NSString *)url xml:(NSString *)xmlData;
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
-(void)connectionDidFinishingLoading:(NSURLConnection *)connection;
@end
@implementation ServiceRouter
- (void)postXMLToURL:(NSString *)url xml:(NSString *)xmlData
{
NSLog(@"Posting XML to URL: %@", url);
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/xml" forHTTPHeaderField:@"Content-type"];
[request setValue:@"application/xml" forHTTPHeaderField:@"Accept"];
[request setValue:[NSString stringWithFormat:@"%d", [xmlData length]] forHTTPHeaderField:@"Content-length"];
[request setHTTPBody:[xmlData dataUsingEncoding: NSUTF8StringEncoding]];
NSURLConnection *connection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
if(connection) {
NSLog(@"Connection created");
receivedData = [[NSMutableData data] retain];
} else {
NSLog(@"Issue with connection!");
}
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
if([response respondsToSelector:@selector(statusCode)])
{
int statusCode = [((NSHTTPURLResponse *)response) statusCode];
NSLog(@"HTTP Response code: %i", statusCode);
}
NSLog(@"Received response");
[receivedData setLength:0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"Received data: %@", data);
[receivedData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[connection release];
[receivedData release];
NSLog(@"Connection failed! Error - %@", [error localizedDescription]);
}
-(void)connectionDidFinishingLoading:(NSURLConnection *)connection
{
NSLog(@"Succeeded! Received %d bytes of data", [receivedData length]);
[connection release];
[receivedData release];
}
@end
Here's my ServiceImplementation class:
@interface ServiceImplementation : ServiceRouter {
}
-(void) createServiceSpecificXML;
@end
@implementation ServiceImplementation
-(void) createServiceSpecificXML
{
NSString *xmlData = @"<example><ignore/></example>";
[super postXMLToURL:@"http://site.com/endpoint.xml" xml:xmlData];
}
@end