sabeer mohamed
sabeer mohamed

Reputation: 3

How to use more than one delegate in iphone?

I am using below code to use json but i need more url connection in same page, how to achive it, thanks in advance

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[responseData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog([NSString stringWithFormat:@"Connection failed: %@", [error description]]);
 }

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
//do something with the json that comes back ... (the fun part)
}

- (void)viewDidLoad
{
[self searchForStuff:@"iPhone"];

}

-(void)searchForStuff:(NSString *)text
 {
responseData = [[NSMutableData data] retain];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL   URLWithString:@"http://www.whatever.com/json"]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}

I am using php for web access

Upvotes: 0

Views: 210

Answers (4)

codecaffeine
codecaffeine

Reputation: 894

You don't actually need more than one delegate. You need more than one NSURLConnection and you can test to see which one is calling the delegate method.

For example. Assuming the following instance variable (or properties):

NSURLConnection *connectionA;
NSURLConnection *connectionB;
NSMutableData *dataA;
NSMutalbeData *dataB;

First you instantiate each NSURLConnection variable

-(void)searchA:(NSString *)text
{
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://www.a.com/%@", text]]];
    connectionA = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

-(void)searchB:(NSString *)text
{
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://www.b.com/%@", text]]];
    connectionB = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

Then you can test to see which connection is calling the delegate method and customize the implementation based on the connection

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    if (connection == connectionA) {
        [dataA appendData:data];
    }
    else if (connection == connectionB) {
        [dataB appendData:data];
    }
}

You'll need to do this for each delegate method.

Upvotes: 0

Benjie
Benjie

Reputation: 7946

As NSValue conforms to NSCopying I use it to wrap the pointer to the connection, and use this as the key to access relevant data from a NSMutableDictionary. For example you might do something like the following:

-(void)searchForStuff:(NSString *)text withTarget:(id)target selector:(SEL)selector {
    responseData = [[NSMutableData data] retain];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.whatever.com/json"]];
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:target,@"target",NSStringFromSelector(selector),@"selector",nil];
    NSURLConnection *c = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [myMutableDictionary setObject:options forKey:[NSValue valueWithPointer:c]];
    [c release];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSValue *p = [NSValue valueWithPointer:connection];
    NSDictionary *options = [myMutableDictionary objectForKey:p];
    if (options) {
        id target = [options objectForKey:@"target"];
        SEL selector = NSSelectorFromString([options objectForKey:@"selector"]);
        if (target && selector && [target respondsToSelector:selector]) {
            [target performSelector:selector withObject:responseData];
        }
    }
}

Upvotes: 1

Dan Ray
Dan Ray

Reputation: 21893

Don't do any of that.

Instead use the brilliant ASIHTTPRequest library, which makes everything much simpler and better. Literally, since I discovered ASI a couple years ago, I haven't written a single NSURLConnection, not one.

ASI's block interface lets you configure a request object with its handler code before firing it, and does away with any need for delegation.

__block ASIHTTPRequest *r = [ASIHTTPRequest requestWithUrl:myNSURLObject];
[r setCompletionBlock:^{
    NSLog([r responseString]); //for instance
}];
[r startAsynchronous];

If blocks scare you, you can also point a particular request at a particular method, so different request types can be handled separately:

- (void) viewDidLoad { //or wherever
    ASIHTTPRequest *r = [ASIHTTPRequest requestWithUrl:myFirstURL];
    r.delegate = self;
    [r setDidFinishSelector:@selector(requestDone:)];
    [r startAsynchronous];
}

// then later on...
- (void)requestDone:(ASIHTTPRequest *)request
{
   NSString *response = [request responseString];
}

Upvotes: 0

Rengers
Rengers

Reputation: 15218

You could use instance variables to keep pointers to the connections. Then in the delegate callbacks, check for pointer equality to check which connection you're dealing with.

Upvotes: 2

Related Questions