Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load huge amount of data from a web service in a UITableView?

I'm currently building an app that will have a UITableView that will get it's data from a web service. The returned data can contain a large amount of records, for example 50,000 records. I know that all the records can not be loaded into an array at once, this will make the app non responsive because of the lack of memory. The web service I'm calling receives parameters for page size and page number so it will only returned the data that I want to show to the user. But I have not found any method that will indicate me that the user has scrolled all the displayed record and needs to get the new data from the service. The screen has also a search bar and a search button that when pressed will call another service that returns the result of the search. This will have the same problem as earlier since the result could bring lots of records too.

What will be the best way to do this?

like image 266
Angie Avatar asked Mar 15 '12 14:03

Angie


2 Answers

Ok there are several approaches to this problem. One that is very popular is the implementation of three20 framework (Internet-aware table view controllers)

As for your second question the tableview's delegate has a handy method:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

UPDATE:

After exactly one year since this answer was posted, I would recommend you to use RestKit. Many people think that it has a steep learning curve but it's a really great framework for handling restful resources and includes cache management, core data integration / mapping and a paginator (among others) which pretty much cover all your requirements.

like image 58
Alladinian Avatar answered Nov 14 '22 03:11

Alladinian


We are currently doing something similar in our application. Since UITableView inherits from UIScrollView, you will probably want to take advantage of some of UIScrollView's properties and methods. You will almost definitely want to implement a class that conforms to UIScrollView delegate. Then, when the user scrolls to the bottom of the currently loaded records in the UITableView, you can query the web service for the next page of data. The documentation for UIScrollView is here and the documentation for UIScrollViewDelegate here.

Here's an example implementation of the scrollViewDidScroll: method of UIScrollViewDelegate which should get you the behavior of loading records when the user reaches the bottom of the scroll view.

- (void) scrollViewDidScroll:(UIScrollView *) scrollView {
    // Calculate whether the user has reached the bottom of the scroll view.
    CGPoint offset = scrollView.contentOffset;
    CGRect bounds = scrollView.bounds;
    CGSize size = scrollView.contentSize;
    UIEdgeInsets inset = scrollView.contentInset;
    float y = offset.y + bounds.size.height - inset.bottom;
    float h = size.height;
    float reload_distance = 0;
    if (y >= h + reload_distance) {
        // Request next page of data here.
    }
}

The beauty of the UITableViewDataSource methods is that they do not require that you have your data stored in memory. You can provide the necessary data for each cell requested on demand when tableView:cellForRowAtIndexPath: is called. Similarly, you can provide the value to return from tableView:numberOfRowsInSection: without actually having all of the data for the rows in memory. You will most likely want to keep data for cells around the currently viewed in cells in memory, however, to ensure reasonable performance. Unfortunately, this may all be rather tricky, but it should be possible. You can find more documentation about UITableDataSource here.

like image 3
Steven Oxley Avatar answered Nov 14 '22 04:11

Steven Oxley