views:

62

answers:

2

Hello all,

I've my own class which should do the request and the data processing (parsing). This class should be used from different view controllers. In this class I have implemented:

- (void)sendRequest:(NSString *)url;
- (void)requestFinished:(ASIHTTPRequest *)request;
- (void)requestFailed:(ASIHTTPRequest *)request;
- (id)parse:(NSString *)aString;

I have created a property called result. If the request arrives, requestFinished is called. In requestFinished the results are saved in result. I thought if I return a value in sendRequest I get the result back. But as I mentioned before requestFinished gets the result and so sendRequest is always returning a nil variable, because at that time the request isn't finished.

What can I do to return a result? I want that this class can be used from different view controllers. So my first thought creating a method in my view controller and passing the result won't work.

I read this thread http://stackoverflow.com/questions/2878640/pass-result-of-asihttprequest-requestfinished-back-to-originating-method about using the view controller as delegate. But then I think I have to implement requestFinished and requestFailed in the view controller. The idea of not having duplicate code in different view controllers would be gone away ...

Can someone help?

A: 

Post an observer notification whenever you get the result and have your viewcontrollers add themselves as listeners to this notification (receiving it via [notification object]).

vakio
So I found a solution, but I've no idea how to implement the observer pattern. Perhaps you could provide a link to a tutorial or something like that.
testing
A: 

So finally I did it with a delegate.

In my abstraction class (*.h) I defined the following, otherwise you get

warning: no '-setDarkness: ' method found

warning: (Messages without a matching method signature will be assumed

warning: to return 'id' and accept '.. .' as arguments.)

@protocol RssParserDelegate <NSObject>  
    - (void)displayResults:(NSDictionary *)parserResults;
@end

Than I declared an instance variable and some methods in my abstraction class (*.h):

id _delegate;
// ...
- (id)delegate;  
- (void)setDelegate:(id)new_delegate;

The declaration therefore looks like (*.m):

 - (id)delegate {  
     return _delegate;  
 }  

 - (void)setDelegate:(id)new_delegate {  
     _delegate = new_delegate;  
 }

To pass the result you have to put the following code on requestFailed and requestFinished:

if ([_delegate respondsToSelector:@selector(displayResults:)])
    [_delegate displayResults:results];
else  
{   
    [NSException raise:NSInternalInconsistencyException  
                format:@"Delegate doesn't respond to displayResults:"];  
}

I redefined sendRequest and set the incoming delegate to my instance variable:

- (void)sendRequest:(NSString *)url withDelegate:(id)aDelegate {
    // set delegate to populate the results later
    [self setDelegate:aDelegate]; 

In your view controller declare this method:

- (void)displayResults:(NSDictionary *)results {
     // do some data processing
     ...
     // show data
     [self.tableView reloadData];
}

And I also changed the method call to sendRequest of my abstraction class:

[yourRequest sendRequest:@"xxx" withDelegate:self]; 
testing