Many iOS apps connect to HTTP-based APIs, which may be RESTful but are often just XML and JSON responses to various URLs with various methods (usually a GET or POST, but also PUT and DELETE). There’s no one methodology for talking to these types of APIs in an iOS app, but here’s the basic process I use.
If the web service happens to be a Ruby on Rails application and follows the standard RESTful practices, then Objective Resource is a great tool.
If not, then what I tend to do is use ASIHTTPRequest which provides a nice network layer. Depending on the API, I might use ASI objects directly, or else I’ll subclass an existing ASI class to add per-request functionality (such as authentication or response parsing).
You usually want to run web requests in the background, so that the UI isn’t blocked while waiting for the request to finish. There’s always the background thread route, but a nice “Objective C” style approach that ASIHTTPRequest provides is to instead provide a delegate which is called when the request finishes (see also “Creating an asynchronous request” at http://allseeing-i.com/ASIHTTPRequest/How-to-use). In many cases the request delegate is the view controller that initiates the request.
The model layer depends on the complexity, and also what format the data comes in. Most of the APIs I’ve worked with use JSON, for which json-framework or yajl-objc are good for parsing. These usually give the data parsed into base classes like NSString, NSArray and NSDictionary. Sometimes that’s sufficient, or if I want the models to exist as their own classes, then I have the models inherit from a base class that takes care of turning the NSDictionary/NSArray into properties.
Finally for caching, Core Data provides a good way to persist to disk. For caching in memory, I have the requests occur in a separate “manager” class that is shared between controllers. These managers use the Singleton design pattern as described here.