I have a class WebServiceCaller that uses NSURLConnection to make asynchronous calls to a web service. The class provides a delegate property and when the web service call is done, it calls a method webServiceDoneWithXXX on the delegate.
There are several web service methods that can be called, two of which are say GetSummary and GetList.
The classes that use WebServiceCaller initially need both the summary and list so they are written like this:
-(void)getAllData {
[webServiceCaller getSummary];
}
-(void)webServiceDoneWithGetSummary {
[webServiceCaller getList];
}
-(void)webServiceDoneWithGetList {
...
}
This works but there are at least two problems:
- The calls are split across delegate methods so it's hard to see the sequence at a glance but more important it's hard to control or modify the sequence.
- Sometimes I want to call just GetSummary and not also GetList so I would then have to use an ugly class-level state variable that tells webServiceDoneWithGetSummary whether to call GetList or not.
Assume that GetList cannot be done until GetSummary completes and returns some data which is used as input to GetList.
Is there a better way to handle this and still get asynchronous calls?
Update based on Matt Long's answer:
Using notifications instead of a delegate, it looks like I can solve problem #2 by setting a different selector depending on whether I want the full sequence (GetSummary+GetList) or just GetSummary. Both observers would still use the same notification name when calling GetSummary. I would have to write two separate methods to handle GetSummaryDone instead of using a single delegate method (where I would have needed some class-level variable to tell whether to then call GetList).
-(void)getAllData {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(getSummaryDoneAndCallGetList:)
name:kGetSummaryDidFinish object:nil];
[webServiceCaller getSummary];
}
-(void)getSummaryDoneAndCallGetList {
[NSNotificationCenter removeObserver]
//process summary data
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(getListDone:)
name:kGetListDidFinish object:nil];
[webServiceCaller getList];
}
-(void)getListDone {
[NSNotificationCenter removeObserver]
//process list data
}
-(void)getJustSummaryData {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(getJustSummaryDone:) //different selector but
name:kGetSummaryDidFinish object:nil]; //same notification name
[webServiceCaller getSummary];
}
-(void)getJustSummaryDone {
[NSNotificationCenter removeObserver]
//process summary data
}
I haven't actually tried this yet. It seems better than having state variables and if-then statements but you have to write more methods. I still don't see a solution for problem 1.