views:

199

answers:

2

I'm sorry if this is a basic question. I've been googling, searching StackOverflow, and looking through example code for hours and haven't found anything satisfactory for my skill level.

I'm wanting something like a design pattern for handling network functions on the iPhone SDK. I have heard of people using a singleton class but have heard there are better ways for asynchronous connections. Would NSOperation be useful? I am fairly new to object oriented programming but am needing to make occasional calls to my webserver through HTTP for my current app and hope to find a solution that is easily reusable.

I've looked through the NSURLConnection docs and can get the basic functionality but the programming structure is messy and I'm not sure how to better organize it. Is there sample code for this that separates out these functions into their own class? A link to an example that does this would be greatly appreciated! thanks!

A: 

One possible approach is to use the NSURLConnection (as you mentioned).

Inside your .h file:

NSMutableData *connectionData;

Also add a property for connectionData...

Inside your .m file:

- (void)updateFromServer {
    // You might want to display a loading indication here...

    NSMutableData *connectionDataTemp = [[NSMutableData alloc] init];
    self.connectionData = connectionDataTemp;
    [connectionDataTemp release];

    NSURLRequest *request = [[NSURLRequest alloc] initWithURL: your_url];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [connection release];
    [request release];
}

#pragma mark -
#pragma mark NSURLConnectionDelegate

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    // Add the received bulk of data to your mutable data object
    [self.connectionData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    // Use your data

    // If there is a loading indication displayed then this is a good place to hide it...
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    // Handle error

    // If there is a loading indication displayed then this is a good place to hide it...
}
Michael Kessler
Thanks for the reply. Would this best be placed in my AppDelegate or in a view controller? or should I have a connection class and instantiate it in each of my view controller classes when needed?
feesta
It depends on your needs. If you use it only in one view controller then I'd definitely place it there. I wouldn't place this functionality in app delegate for sure (I try to avoid using it as code container). If you use the connection thing from many view controllers you could place it in some external class, BUT, usually, the code inside the callbacks is private for the view that called it, so it might be tricky to use it this way (you may implement your own protocol with methods like showLoading, hideLoading, dataReceived etc.).
Michael Kessler
Another possible approach is to implement a base view controller that will implement all these methods (some default implementation) and you will override the implementation in each concrete view controller...
Michael Kessler
A: 

I've been dealing with this same question for a while now...

1) If you're effectively doing a GET on a simple resource, and you're confident that the resource will always be there & accessible, there's an easy way to do it:

NSURL *URL=[[NSURL alloc] initWithString:@"http://www.google.com/"l];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
//TODO This needs to have timeouts & such set up, maybe parallelism
NSString *results = [[NSString alloc] initWithContentsOfURL :URL];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

That's a REALLY simple way to do it, but as my comment says, not very robust or reliable.

2) A slightly more robust, yet still reasonably simple, is replacing the NSString line with:

results = [[NSString alloc] initWithContentsOfURL:URL encoding:NSASCIIStringEncoding error:&err]; // possibly NSUnicodeStringEncoding
if (err!=nil) NSLog(@"Error occurred: %@", [err localizedDescription]);

That will at least TELL you if there's an error...

3) ASIHTTPRequest provides a lot of neat & useful network functionality for dealing with resources over the internet. http://allseeing-i.com/ASIHTTPRequest/ - the developer has been VERY responsive on his Google Group. I really wanted to use that, and may get back to it when/if it supports SSL Client Certificate authentication (which is what my project requires).

4) NSURLConnection, as described above - that's what I'm using now in my project. I would imagine that this will satisfy almost all needs, but it's (in my opinion) more tricky to use. And to be honest, I'm still having a little trouble wrapping my mind around how to integrate asynchronous data loading into my application. But if it will work for you - and it probably will, Apple is using it all over the OS and its apps - that's your best bet!

Good luck and have fun! -=Alan

Alan D.