2013-10-10 3 views
0

У меня есть следующий метод retrieveData в моем классе SendData. Я называю этот класс из моего MovieViewController. Метод проверяет правильность данных, полученных с сервера, если он есть, он возвращает TRUE. Если это не так, он возвращает FALSE. Он отлично работает, за исключением того, что метод возвращается в мой MovieViewController, прежде чем данные успеют «загрузить». Следовательно, метод всегда возвращает false, потому что он всегда равен нулю, потому что управление возвращается в исходный контроллер представления.Извлечь данные NSURL при загрузке

Как вернуть (выход AKA с помощью метода с возвращаемым значением) только после того, как данные закончили загрузку, а не раньше?

Спасибо!

SendData.m

-(BOOL)retrieveData:(NSString *) postID:(NSString *) message:(NSString *)token 
{ 

    __block BOOL value=FALSE; 
    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; 
    sessionConfiguration.HTTPAdditionalHeaders = @{ 
                @"message" : message, 
                @"access_token": token 
                }; 

    postID=[NSString stringWithFormat:@"https://graph.facebook.com/%@/comments?message=%@&access_token=%@",postID,message,token]; 
    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration]; 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:postID]]; 
    request.HTTPMethod = @"POST"; 
    NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
     //THIS NEEDS TO BE EXECUTED BEFORE THE METHOD IS RETURNED 
     BOOL valid; 
     NSString* myString; 
     myString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; 
     NSLog(@"MY string is %@", myString); 

     if (myString != NULL || [myString length] != 0) 
     { 
      valid = TRUE; 
     } 
     else 
     { 
      valid = FALSE; 
     } 
     value=valid; 
    }]; 
    return value; 

} 

ответ

1

Вы можете сделать это с помощью шаблона делегата. Вы должны добавить следующее свойство SendData

@property (nonatomic, weak) id delegate; 

и метод:

- (void)dataDownloaded:(NSNumber *)result 

MovieViewController в.

Тогда в MovieViewController вы должны установить (я предполагаю здесь, что SendData является объектом класса SendData):

sendData.delegate = self; 

Тогда вы должны изменить определение:

-(void)retrieveData:(NSString *) postID:(NSString *) message:(NSString *)token 
{ 
    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; 
    sessionConfiguration.HTTPAdditionalHeaders = @{ 
                @"message" : message, 
                @"access_token": token 
                }; 

    postID=[NSString stringWithFormat:@"https://graph.facebook.com/%@/comments?message=%@&access_token=%@",postID,message,token]; 
    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration]; 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:postID]]; 
    request.HTTPMethod = @"POST"; 
    NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
     //THIS NEEDS TO BE EXECUTED BEFORE THE METHOD IS RETURNED 
     BOOL valid; 
     NSString* myString; 
     myString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; 
     NSLog(@"MY string is %@", myString); 

     if (myString != NULL || [myString length] != 0) 
     { 
      valid = TRUE; 
     } 
     else 
     { 
      valid = FALSE; 
     } 

     [self.delegate performSelectorOnMainThread:@selector(dataDownloaded:) withObject:@(valid) waitUntilDone:NO]; 
    }]; 
} 

Вы могли бы также проверьте, если self.delegate отвечает на dataDownloaded: с:

[self.delegate respondsToSelector:@selector(dataDownloaded:)] 

В качестве альтернативы вместо шаблона делегата вы можете использовать блоки или NSNotificationCenter.

+0

Спасибо Аркадиусу! Просто интересно, я читал, что выступление на главной теме - не очень хорошая идея. Вы согласны? – Teddy13

+0

Конечно. Выполнение этого в фоновом потоке требует пересмотра вашей архитектуры. С моими изменениями вы узнаете, удалось ли выполнить запрос только тогда, когда вызывается 'dataDownloaded:'. Но это, безусловно, было бы лучше с точки зрения пользователя. –

+0

Вижу, спасибо. Один из последних вопросов, я довольно новичок в iOS dev (я студент), вызывает performSelectorInBackground, как это сделать? Благодаря! – Teddy13

0

Это может быть сделано с помощью NSURLConnection, но не запускать это в основном потоке или у вас есть очень реальный шанс замораживания приложения для нескольких минут во время ожидания запроса для завершения:

NSError *error = nil; 
NSURLResponse *response = nil; 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:postID]]; 
request.HTTPMethod = @"POST"; 
[request addValue:message forHTTPHeaderField:@"message"]; 
[request addValue:token forHTTPHeaderField:@"access_token"]; 
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 
NSString *myString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; 
+0

Спасибо, как бы я запустил это в фоновом режиме? – Teddy13

Смежные вопросы