2014-09-14 3 views
1

я называю GET API, который принимает строку ключевое слово и возвращает мне данные в формате JSON, который я синтаксический анализ и отображение в моем UITableViewКак отображать UIActivityIndicatorView, когда данные JSON асинхронно заполняются в UITableView?

Хотя возвращает данные API, я отображая UIActivityIndicatorView, это работает отлично. Однако, как только данные будут получены, UIActivityIndicatorView исчезнет, ​​как ожидалось, но данные не отображаются в UITableView, но если я прикасаюсь в любом месте экрана, данные становятся видимыми в пользовательском интерфейсе TableView.

Это мой код:

-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar 
{ 
    [indicator startAnimating]; 
    indicator.hidesWhenStopped = YES; 

    dispatch_queue_t queue = dispatch_queue_create("ID", NULL); 
    dispatch_async(queue, ^{ 
     NSString *searchText=searchBar.text; 
     NSString *trimmedString = [searchText stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]]; 
     if (trimmedString.length==0) { 
      isFilter=NO; 

      UIAlertView *noConn = [[UIAlertView alloc] initWithTitle:@"ERROR" message:@"Please enter something in search bar" delegate:self cancelButtonTitle:nil otherButtonTitles:@"ok", nil]; 
      [noConn show]; 
     } else { 
      NSString *searchNew = [trimmedString stringByReplacingOccurrencesOfString:@" " withString:@"%20"]; 
      isFilter=YES; 
      @try { 
       [label removeFromSuperview]; 
       _Title1 = [[NSMutableArray alloc] init]; 
       _Author1 = [[NSMutableArray alloc] init]; 
       _Images1 = [[NSMutableArray alloc] init]; 
       _Details1 = [[NSMutableArray alloc] init]; 
       _link1 = [[NSMutableArray alloc] init]; 
       _Date1 = [[NSMutableArray alloc] init]; 
       NSString* myURLString = [NSString stringWithFormat:@"www.example.com=%@", searchNew]; 
       NSURL *url = [NSURL URLWithString:myURLString]; 

       NSData* data = [NSData dataWithContentsOfURL:url]; 

       if ((unsigned long)data.length > 3) { 
        NSArray *ys_avatars = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; 
        if(ys_avatars) { 
         for (int j=0;j<ys_avatars.count;j++) { 
          if(ys_avatars[j][@"title"]==[NSNull null]) { 
           [_Title1 addObject: @""]; 
          } else { 
           [_Title1 addObject:ys_avatars[j][@"title"]]; 
          } 

          if(ys_avatars[j][@"author"]==[NSNull null]) { 
           [_Author1 addObject: @""]; 
          } 

          [_Author1 addObject: ys_avatars[j][@"author"]]; 

          if(ys_avatars[j][@"featured_img"]==[NSNull null]) { 
           [_Images1 addObject: @""]; 
          } else { 
           [_Images1 addObject: ys_avatars[j][@"featured_img"]]; 

          } 

          if(ys_avatars[j][@"content"]==[NSNull null]) { 
           [_Details1 addObject: @""]; 
          } else { 
           [_Details1 addObject:ys_avatars[j][@"content"]]; 
          } 

          if(ys_avatars[j][@"permalink"]==[NSNull null]) { 
           [_link1 addObject: @""]; 
          } else { 
           [_link1 addObject:ys_avatars[j][@"permalink"]]; 
          } 

          if(ys_avatars[j][@"date"]==[NSNull null]) { 
           [_Date1 addObject: @""]; 
          } else { 
           NSString *newStr=[ys_avatars[j][@"date"] substringToIndex:[ys_avatars[j][@"date"] length]-3]; 
           [_Date1 addObject:newStr]; 
          } 
         } 
        } else { 
         NSLog(@"error"); 
        } 
        [self.myTableView reloadData]; 
       } else { 
        if(IDIOM == IPAD){ 
         [self.myTableView reloadData]; 

         self.tableView.separatorColor = [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.0]; 

         label = [[UILabel alloc] initWithFrame:CGRectMake(150, 200, 200, 100)]; 
         [email protected]"No Article Found"; 
         label.backgroundColor = [UIColor clearColor]; 
         [self.view addSubview:label]; 
        } else { 
         [self.myTableView reloadData]; 
         self.tableView.separatorColor = [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.0]; 
         label = [[UILabel alloc] initWithFrame:CGRectMake(90, 100, 200, 100)]; 
         [email protected]"No Article Found"; 
         label.backgroundColor = [UIColor clearColor]; 
         [self.view addSubview:label]; 
        } 
       } 
      } 
      @catch (NSException *exception) { } 
     } 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [indicator performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:YES]; 
     }); 
    }); 

    [self.mySearchBar resignFirstResponder]; 
} 

ответ

4

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

Обычно самый простой способ сделать это с помощью:

dispatch_async(dispatch_get_main_queue(), ^{ 
    // code to run on the main queue 
}); 

Я действительно вижу, что вы используете, что при остановке UIActiviteIndicatorView здесь:

dispatch_async(dispatch_get_main_queue(), ^{ 
    [indicator performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:YES]; 
}); 

Но в том, что case, вы фактически отправляете метод stopAnimating в основную очередь дважды. Вы только действительно это нужно:

dispatch_async(dispatch_get_main_queue(), ^{ 
    [indicator stopAnimating]; 
}); 

Что касается вашей таблицы не обновляется, это потому, что вам нужно направить все свои reloadData вызов в основную очередь.

В вашем коде есть довольно много мест, которые необходимо отправить обратно в основную очередь, но вместо того, чтобы обернуть все из них в dispatch_async в основную очередь, есть более простой способ. Единственное место, где я вижу, где вы на самом деле делать то, что должно быть сделано на фоне потока эта линия:

NSData* data = [NSData dataWithContentsOfURL:url]; 

Что означает, что вы можете избавиться от dispatch_async(queue, ^{...}); в начале вашего метода и, вместо этого, только сделайте это как раз перед тем, как позвонить [NSData dataWithContentsOfUrl:url]. Затем, dispatch_async обратно в главную очередь сразу после.

Как это:

-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar 
{ 
    [indicator startAnimating]; 
    indicator.hidesWhenStopped = YES; 

    NSString *searchText=searchBar.text; 
    NSString *trimmedString = [searchText stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]]; 
    if (trimmedString.length==0) { 
     isFilter=NO; 

     UIAlertView *noConn = [[UIAlertView alloc] initWithTitle:@"ERROR" message:@"Please enter something in search bar" delegate:self cancelButtonTitle:nil otherButtonTitles:@"ok", nil]; 
     [noConn show]; 
    } else { 
     NSString *searchNew = [trimmedString stringByReplacingOccurrencesOfString:@" " withString:@"%20"]; 
     isFilter=YES; 
     @try { 
      [label removeFromSuperview]; 
      _Title1 = [[NSMutableArray alloc] init]; 
      _Author1 = [[NSMutableArray alloc] init]; 
      _Images1 = [[NSMutableArray alloc] init]; 
      _Details1 = [[NSMutableArray alloc] init]; 
      _link1 = [[NSMutableArray alloc] init]; 
      _Date1 = [[NSMutableArray alloc] init]; 
      NSString* myURLString = [NSString stringWithFormat:@"www.example.com=%@", searchNew]; 
      NSURL *url = [NSURL URLWithString:myURLString]; 

      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
       NSData* data = [NSData dataWithContentsOfURL:url]; 

       dispatch_async(dispatch_get_main_queue(), ^{ 
        if ((unsigned long)data.length > 3) { 
         NSArray *ys_avatars = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; 
         if(ys_avatars) { 
          for (int j=0;j<ys_avatars.count;j++) { 
           if(ys_avatars[j][@"title"]==[NSNull null]) { 
            [_Title1 addObject: @""]; 
           } else { 
            [_Title1 addObject:ys_avatars[j][@"title"]]; 
           } 

           if(ys_avatars[j][@"author"]==[NSNull null]) { 
            [_Author1 addObject: @""]; 
           } 

           [_Author1 addObject: ys_avatars[j][@"author"]]; 

           if(ys_avatars[j][@"featured_img"]==[NSNull null]) { 
            [_Images1 addObject: @""]; 
           } else { 
            [_Images1 addObject: ys_avatars[j][@"featured_img"]]; 

           } 

           if(ys_avatars[j][@"content"]==[NSNull null]) { 
            [_Details1 addObject: @""]; 
           } else { 
            [_Details1 addObject:ys_avatars[j][@"content"]]; 
           } 

           if(ys_avatars[j][@"permalink"]==[NSNull null]) { 
            [_link1 addObject: @""]; 
           } else { 
            [_link1 addObject:ys_avatars[j][@"permalink"]]; 
           } 

           if(ys_avatars[j][@"date"]==[NSNull null]) { 
            [_Date1 addObject: @""]; 
           } else { 
            NSString *newStr=[ys_avatars[j][@"date"] substringToIndex:[ys_avatars[j][@"date"] length]-3]; 
            [_Date1 addObject:newStr]; 
           } 
          } 
         } else { 
          NSLog(@"error"); 
         } 
         [self.myTableView reloadData]; 
        } else { 
         if(IDIOM == IPAD){ 
          [self.myTableView reloadData]; 

          self.tableView.separatorColor = [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.0]; 

          label = [[UILabel alloc] initWithFrame:CGRectMake(150, 200, 200, 100)]; 
          [email protected]"No Article Found"; 
          label.backgroundColor = [UIColor clearColor]; 
          [self.view addSubview:label]; 
         } else { 
          [self.myTableView reloadData]; 
          self.tableView.separatorColor = [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.0]; 
          label = [[UILabel alloc] initWithFrame:CGRectMake(90, 100, 200, 100)]; 
          [email protected]"No Article Found"; 
          label.backgroundColor = [UIColor clearColor]; 
          [self.view addSubview:label]; 
         } 
        } 

        [indicator stopAnimating]; 
       }); 
      }); 
     } 
     @catch (NSException *exception) { } 
    } 

    [self.mySearchBar resignFirstResponder]; 
} 

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

+0

большое спасибо, его работа абсолютно прекрасна. Это именно то, что я искал. – Daljeet

+0

еще раз спасибо за этот ответ, у меня есть еще один запрос, пожалуйста, помогите мне. вот ссылка: http://stackoverflow.com/questions/25838122/json-data-is-not-loading-in-slow-internet-connection – Daljeet

2

пытаются использовать NSURLConnection, что позволит сэкономить много головной боли и сделать ваши запросы URL более управляемым

@interface myTableView : UITableViewController<NSURLConnectionDelegate>{ 
    NSMutableData *_responseData; 
} 

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

#pragma mark NSURLConnection Delegate Methods 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    // A response has been received, this is where we initialize the instance var you created 
    // so that we can append data to it in the didReceiveData method 
    // Furthermore, this method is called each time there is a redirect so reinitializing it 
    // also serves to clear it 
    _responseData = [[NSMutableData alloc] init]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    // Append the new data to the instance variable you declared 
    [_responseData appendData:data]; 
} 

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection 
        willCacheResponse:(NSCachedURLResponse*)cachedResponse { 
    // Return nil to indicate not necessary to store a cached response for this connection 
    return nil; 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    // The request is complete and data has been received 
    // You can parse the stuff in your instance variable now 

} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    // The request has failed for some reason! 
    // Check the error var 
} 

и сделать запрос URL, куда вы хотите

// Create the request. 
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]]; 

// Create url connection and fire request 
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 

source

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