views:

299

answers:

3

I'm developing an app that will talk with a web service exposing multiple methods. I'm trying to figure out what the best pattern would be to centralize the access to the web service, give options for synchronous and asynchronous access, and return data to clients. Has anybody tackled this problem yet?

One class for all methods seems like it would centralize everything well, but I'm thinking it would get confusing to return data to the correct places, especially when dealing with multiple asynchronous calls. Another thought I had was a separate subclass for each method, with some sort of factory brokering access, but I'm thinking that might be overengineering the situation.

(note: not asking for what method calls to use/how to parse response/etc, looking for a high level design pattern solution to the general problem)

+1  A: 

I recently came across the same problem. While I don't believe my solution to be optimal, it may help you out.

I created a web service manager and an endpoint protocol. Each object that implements the endpoint protocol is responsible for connecting to a web service endpoint(method), parsing the returned data, and notifying its delegate(usually the web service manager) of completion or any errors. I ended up creating an EndpointBase class that I use 99% of the time.

The web service manager is responsible for instantiating the endpoints as needed and invoking them. All of the calls happen asynchronously.

All in all it seems to work pretty well for me. I did end up with a situation in which one endpoint relied on the response of another (I used the command pattern there).

SDK Components that you'll want to look at are:

  • NSURLConnection
  • NSXMLParser
jessecurry
I was heading down the path towards this kind of solution, sounds like I wasn't the only one to think this up. The only difference in my mind is that instead of using delegates, use KVO, since I could potentially have multiple consumers of an endpoint simultaneously. This would also let me inject some sort of caching logic in later, since everything is just observing the same endpoint object.will update later with how this ends up going down.
jenningj
The delegate is mainly to inform the web service manager that the endpoint is done, if the endpoint fails the service manager decides what to do.I use KVO to update the most of the views that use the data.
jessecurry
+1  A: 

Factories? We don't need no stinkin' factories.

I've done this a few times, and I basically do what you're saying: one object that provides methods for all the web service calls, encapsulating the details of communicating with the service, handling connection issues, etc. In one app it was a singleton, because it needed to keep session state; in another app it was just a collection of static methods.

Along with some formatting of the response data, that's the entirety of its responsibility.

It's left up to the callers is whether the call is synchronous or asynchronous; the class itself is written synchronously, and a caller just uses it in a separate thread if necessary. Cocoa's performSelector... methods make that easy.

lawrence
+1  A: 

If REST is a good fit for your data interactions, then I would suggest the ObjectiveResource library . It's designed to work seamlessly with a Ruby on Rails app, but it basically speaks JSON or POX (plain old XML) over HTTP using rails ActiveResource conventions.

It's basically a set of categories on NSObject and some of the primitive object types that will let you make calls like [Dog findAllRemote] to return a list of Dog objects, or [myDog saveRemote] to send changes made to the myDog object back to the server.

Frank Schmitt