Search code examples
iosobjective-cuitableviewfeed

UITableView loading and reloading


I have trouble loading a UITableView with multiple sections. In order to fill it I use a function (fetches feed from Twitter). At the moment the view loads, the function returns NULL values for it's fields, but after a few seconds it returns the desired feed.

However, before the desired feed is returned, the fields in my tableView are shown to be NULL and then they refresh and are filled properly (No NULL values).

My question is, How can I make the tableView cells not load until the feed is properly loaded?

I have the same problem with my Facebook feed, however it crashes because it doesn't even return any of the values.

in ViewDidLoad I have put

[self getTwitterFeed:^() { 

    [self.tableView reloadData];
}];

EDIT here is the code of the method

- (void)getTwitterFeed:(void (^)(void))completion {
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account
                              accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
@try
{
    if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"TwitterLoggedIn"] isEqualToString:@"YES"]) {

        [account requestAccessToAccountsWithType:accountType
                                         options:nil completion:^(BOOL granted, NSError *error)
         {
             if (granted == YES)
             {
                 NSArray *arrayOfAccounts = [account
                                             accountsWithAccountType:accountType];

                 if ([arrayOfAccounts count] > 0)
                 {
                     ACAccount *twitterAccount = [arrayOfAccounts objectAtIndex:[[NSUserDefaults standardUserDefaults] integerForKey:@"TwitterAccountNumber" ]];

                     NSURL *requestURL = [NSURL URLWithString:@"http://api.twitter.com/1.1/statuses/home_timeline.json"];

                     NSMutableDictionary *parameters =
                     [[NSMutableDictionary alloc] init];
                     [parameters setObject:@"35" forKey:@"count"];
                     [parameters setObject:@"true" forKey:@"include_entities"];


                     SLRequest *postRequest = [SLRequest
                                               requestForServiceType:SLServiceTypeTwitter
                                               requestMethod:SLRequestMethodGET
                                               URL:requestURL parameters:parameters];

                     postRequest.account = twitterAccount;

                     [postRequest performRequestWithHandler:
                      ^(NSData *responseData, NSHTTPURLResponse
                        *urlResponse, NSError *error)
                      {
                          self.dataSource = [NSJSONSerialization
                                             JSONObjectWithData:responseData
                                             options:NSJSONReadingMutableLeaves
                                             error:&error];

                          if (self.dataSource.count != 0) {
                              dispatch_async(dispatch_get_main_queue(), ^{
                                  NSLog(@"Description %@",_dataSource);
                                  for(int i=0;i<[_dataSource count];i++)
                                  {
                                      NSMutableString *url = [NSMutableString stringWithFormat: @"https://www.twitter.com/%@/status/%@",[[[_dataSource objectAtIndex:i ]objectForKey:@"user"] valueForKey:@"screen_name"],[[_dataSource objectAtIndex:i ]objectForKey:@"id"]];

                                      [tweetURL addObject:url];

                                      NSMutableString *urlApp = [NSMutableString stringWithFormat: @"twitter://user?screen_name=%@?status?id=%@",[[[_dataSource objectAtIndex:i ]objectForKey:@"user"] valueForKey:@"screen_name"],[[_dataSource objectAtIndex:i ]objectForKey:@"id"]];

                                      [tweetAppURL addObject:urlApp];
                                  }

                                  CGRect frame = CGRectMake (120, 120, 80, 80);
                                  activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame: frame];
                                  activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
                                  activityIndicator.color = [UIColor whiteColor];
                                  [activityIndicator startAnimating];
                                  activityIndicator.hidesWhenStopped=YES;
                                  [self.view addSubview:activityIndicator];



                             completion();

                                  //[self.tableView reloadData];
                              });

                          }
                      }];
                 }
             } else {

             }  

         }];
    }


    else  //IF FEED IS NOT TURNED ON
    {

        [self.tableView reloadData];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Your TWITTER feed is either turned of or isn't initiated!" message:@"Please enable it in Settings" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
    }

         }

@catch (NSException * e) {
    NSLog(@"Exception: %@", e);
}

}


Solution

  • Try something like this

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do something perhaps
    
        // Do any additional setup after loading the view, typically from a nib.
        [self getTwitterFeed:^() { // Completion block
            dispatch_async(dispatch_get_main_queue(), ^{
                               [myTableView reloadData];
                           });
        }];
    }
    
    
    - (void)getTwitterFeed:(void (^)(void))completion {
        // Get the feed and call:
        NSLog(@"We finished receiving the data");
        completion();
    }
    

    And to show the correct number of rows (need to be edited according to # sections)

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return (self.myFeedArray.count == 0 ? 0 : self.myFeedArray.count);
    }
    

    Loading cells

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        if(myFeedArray.count == 0) { // no feeds yet
            NSLog(@"The count in the table is 0");
            UITableViewCell *cell = [[UITableViewCell alloc] init];
            cell.textLabel.text = @"Updating...";
            [cell.textLabel setTextAlignment:NSTextAlignmentCenter];
            [cell.textLabel setAlpha:0.5];
            cell.userInteractionEnabled = NO;
            return cell;
        }
    
        //else do stuff
    
    }