Ega Setya Putra
Ega Setya Putra

Reputation: 1695

How to display UIActivityIndicatorView while fetching JSON data to be populated in UITableView?

I have a problem with my application.It freeze for several second when I tap the sidebar menu.

What happen when I tapped menu is I pass string that gonna be url for json data fetch in my mainviewcontroller.Then it freeze because I fetch the data and populating data in tableview.

However I really new to ios programming,I wonder how can I remove the freeze?.

thanks in advance

here is my code snippet for the mainviewcontroller:

Upvotes: 0

Views: 652

Answers (4)

Mihir Oza
Mihir Oza

Reputation: 2796

I Prefer MBProgressHUD.
Here is the link for 3rd Party API.
https://github.com/jdg/MBProgressHUD

Just copy these two files in your app.

  • MBProgressHUD.h
  • MBProgressHUD.m

Upvotes: 0

Recycled Steel
Recycled Steel

Reputation: 2272

Instead of using dataWithContentsOfURL (which will block the main thread and so the UI) you need to start an asynchronous connection. In the IF ELSE change the two requests to something like below. The completionHandler (Block) is executed when done, the data parsed, HUD removed and table Updated.

You can even (and in fact must) do this within your cellForRowAtIndexPath for each of the images, however, I would use SDWebImage as it has a cache and is very easy to use.

There are also other methods if this is not right for you such as NSURLSession.

Some other points; I have also noted that the HUD is stopped on every iteration of the FOR and probably should be outside.
I also can not see how your data is being loaded so I added a [myTable reloadData]; I can not see that the "dictionary" object is needed as it can be added directly to the array (see code)

// If you have the status bar showing
// [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

[HUD showUIBlockingIndicatorWithText:@"Please wait. . ."];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:kategori]];
[request setTimeoutInterval: 10.0];
[NSURLConnection sendAsynchronousRequest:request
        queue:[NSOperationQueue currentQueue]
        completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
        {

             // [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

             if (data != nil && error == nil)
             {
                 //All Worked
                 id jsonObjects = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
                 for (NSDictionary *dataDict in jsonObjects)
                 {
                     NSString *title_data = [dataDict objectForKey:@"title"];
                     NSString *thumbnail_data = [dataDict objectForKey:@"thumb"];
                     NSString *author_data = [dataDict objectForKey:@"creator"];
                     NSString *link_data  = [dataDict objectForKey:@"link"];

                     [myObject addObject:[[NSDictionary alloc]initWithObjectsAndKeys:
                          title_data, title,
                          thumbnail_data, thumbnail,
                          author_data,author,
                          link_data,link,
                          nil]];

                 }
                 [HUD hideUIBlockingIndicator];
                 [myTableView reloadData];
             }
             else
             {
                 // There was an error
             }

     }];

For the images something like (this is not tested). I am not sure what format your images are in but you should be able to just add it, this may need tweeking;

cell.imageView.frame = CGRectMake(0, 0, 80, 70);
__block UIImageView *cellImage = cell.imageView;

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[tmpDict objectForKey:thumbnail]]];
[request setTimeoutInterval: 10.0];
[NSURLConnection sendAsynchronousRequest:request
        queue:[NSOperationQueue currentQueue]
        completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
        {
             if (data != nil && error == nil)
             {
                 //All Worked
                 cellImage.image = [[UIImage alloc]initWithData:data];
                 [cellImage layoutIfNeeded];
             }
             else
             {
                 // There was an error
             }

     }];

Upvotes: 0

abhishekkharwar
abhishekkharwar

Reputation: 3529

You can start activity indicator and call fetch data method after few time...

- (void)viewDidLoad{

   [activityIndicator startAnimating];
          [self performSelector:@selector(fetchData) withObject:nil afterDelay:0.5];

}

- (void)fetchData{
     Fetch your data over here
}

Or ideally you have to load data Asynchronous

For loading data Asynchronously check out the following link-

iphone-synchronous-and-asynchronous-json-parse

Upvotes: 0

Wain
Wain

Reputation: 119031

Don't use dataWiyhContentsOfURL:, or at least not directly on the main thread. If you block the main thread then the whole app stops working (as you see).

You need to learn about background threads and callback blocks, and look at using NSURLSession to download your data and then process it.

Upvotes: 1

Related Questions