2016-06-19 4 views
0

Требование - вызвать API edmunds и отобразить имя поставщика в таблице, как только приложение запустится.Как выполнить метод API перед загрузкой таблицы?

1) -getAPIData()

Извлекает имена дилеров и магазинов в self.dealerName массиве.

-(void)getAPIData{ 
    NSURLSession *session = [NSURLSession sharedSession]; 
    self.task = [session dataTaskWithURL:[NSURL URLWithString:[NSString stringWithFormat: 
               @"https://api.edmunds.com/api/dealer/v2/dealers?zipcode=%@&radius=%@&fmt=json&api_key=ycwedw68qast829zx7sn9jnq", 
               @"01609",@"10"]] 
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
     if (data.length > 0 && error == nil) 
     { 
      NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:data 
                    options:kNilOptions 
                    error:NULL]; 
      self.dealersDictionary = jsonData[@"dealers"]; 
      for (id item in self.dealersDictionary){ 
       if (item[@"name"] != nil){ 
        self.dealerName = item[@"name"]; 
        NSLog(@"%@",self.dealerName); 
       }else{ 
        NSLog(@"could'nt find the names"); 
       } 
      } 
     } 
    } 
]; 
} 

2) -viewDidLoad()

Этот метод вызывает getAPIData (выше способом).

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self getAPIData]; 
} 

3) - (NSInteger) Tableview: (UITableView *) TableView numberOfRowsInSection: раздел

(NSInteger) Возвращает число дилеров.

-(NSInteger)tableView:(UITableView *)tableview numberOfRowsInSection:(NSInteger)section 
{ 
    [self.task resume]; 
    return self.dealerName.count; 
} 

getAPIData() метод выполняется после вызова номераOfRowsInSection(). Таким образом, таблица становится пустой.

Как я могу вызвать getAPIData() перед загрузкой таблицы на экран?

ответ

0

Я считаю, что проблема заключается в том, что NSURLSession dataTaskWithURL является асинхронным.

Я думаю вы можете продолжать использовать асинхронный метод и вызвать [self.tableView reloadData]; после возвращения из вызова успешно (например, в обработчике завершения). Вы можете отображать индикатор активности, пока вы ждете завершения загрузки.

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

// define the URL 
NSURL url = [NSURL URLWithString: @"https://api.edmunds.com/api/dealer/v2/dealers?zipcode=%@&radius=%@&fmt=json&api_key=ycwedw68qast829zx7sn9jnq"]; 

// attempt the request 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url 
                cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData 
                timeoutInterval:10]; 
[request setHTTPMethod: @"GET"]; 

NSError *reqError; 
NSURLResponse *urlResponse; 
NSData *returnedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&reqError]; 

// parse `returnedData` here 

Теперь вы будете иметь свой NSData объект, и вы можете разобрать его здесь так же, как вы делали в вашем completionHandler. Этот вариант является жизнеспособным, если вы доверяете, что ответ на запрос будет возвращен быстро.

Окончательный вариант: используйте NSURLConnection для выполнения запроса async и используйте его делегатский метод для обновления UIProgressView для более точного индикатора активности. Я бы посоветовал вам изучить этот метод, если ваше время ответа на запрос достаточно велико, чтобы пользователь задался вопросом, происходит ли что-либо (например, более нескольких секунд).

+0

Спасибо, ваш ответ мне помог. – Sandy

8

Короткий ответ: вы этого не сделаете. Вы показываете пустой табличный вид, а затем в блоке завершения вы вызываете метод reloadData tableView и THEN загружает его содержимое.

+2

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

+0

@ DanielT., Это правда, и, вероятно, хорошая идея. –

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