Как использовать более одного делегата в iphone?

#iphone #json

#iPhone #json

Вопрос:

Я использую приведенный ниже код для использования json, но мне нужно больше URL-адресов на той же странице, как этого добиться, заранее спасибо

 - (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];
}
  

Я использую php для веб-доступа

Ответ №1:

Вы могли бы использовать переменные экземпляра для хранения указателей на соединения. Затем в обратных вызовах делегатов проверьте равенство указателей, чтобы проверить, с каким соединением вы имеете дело.

Комментарии:

1. Что ж, могу я предложить вам сначала создать несколько простых вещей, освоить Objective C, возможно, следовать некоторым руководствам, а затем попробовать это самостоятельно ;). Или просто используйте отличное решение Dan Rays.

Ответ №2:

Поскольку NSValue соответствует NSCopying , я использую его для переноса указателя на соединение и использую это как ключ для доступа к соответствующим данным из a NSMutableDictionary . Например, вы можете сделать что-то вроде следующего:

 -(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 amp;amp; selector amp;amp; [target respondsToSelector:selector]) {
            [target performSelector:selector withObject:responseData];
        }
    }
}
  

Ответ №3:

Не делайте ничего из этого.

Вместо этого используйте блестящую библиотеку ASIHTTPRequest, которая делает все намного проще и лучше. Буквально, с тех пор как я открыл ASI пару лет назад, я не написал ни одного NSURLConnection, ни одного.

Блочный интерфейс ASI позволяет настраивать объект запроса с помощью его кода обработчика перед его запуском и устраняет необходимость в делегировании.

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

Если вас пугают блоки, вы также можете указать конкретный запрос на определенный метод, чтобы разные типы запросов можно было обрабатывать отдельно:

 - (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];
}
  

Комментарии:

1. Хотя мне нравится подход на основе блоков (и хотелось бы, чтобы NSURLConnection использовал его), я бы не стал использовать ASIHTTPRequest, потому что он больше не поддерживается разработчиком. Существуют аналогичные библиотеки, которые все еще поддерживаются. Более подробную информацию см. в блоге ASIHTTPRequest allseeing-i.com

2. @codecaffeine — Вау…. Я понятия не имел. Боже, я чувствую, что член семьи умер или что-то в этом роде. Фух. Думаю, придется начать искать замену. Я ни за что не вернусь к родной агонии.

3. Да, я думаю, что загрузка URL-адресов на основе блоков имеет больше смысла и проще. Я надеюсь, что Apple добавит что-то похожее на NSURLConnection. The allseeing-i.com в блоге упоминается пара альтернатив.

Ответ №4:

На самом деле вам не нужно больше одного делегата. Вам нужно более одного NSURLConnection, и вы можете проверить, какой из них вызывает метод делегирования.

Например. Предполагая следующую переменную экземпляра (или свойства):

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

Сначала вы создаете экземпляр каждой переменной NSURLConnection

 -(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];
}
  

Затем вы можете проверить, какое соединение вызывает метод делегирования, и настроить реализацию на основе этого соединения

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

Вам нужно будет сделать это для каждого метода делегирования.

Комментарии:

1. Вы можете записать все методы делегирования аналогично connection:didReceiveData: . Используйте «if … else if», чтобы настроить поведение на основе каждого соединения.