iOS - 如何使tableview使用分页API输出?

zar*_*don 22 iphone api rest pagination json

我正在编写的API有大约2000条记录,通过我编写的简单RESTful API以JSON形式返回.

为了减少大量数据的问题,我想使用分页,以便我只返回说出每个请求的前10个或前20个,如同offsetlimitpage等.

但我的问题是iOS如何UITableView知道何时获得下一页结果?

我真的不确定如何做到这一点.用户可能正在滚动超高速,因此API可能没有足够的时间一次检索20或50条记录.

与此相关的另一个问题是,假设用户向下滚动UITableView,然后向上然后再向下滚动 - 如何阻止API针对相同的行多次触发?

谢谢

Kun*_*ani 21

似乎是你没有考虑MVC.您的UITableView与分页和webrequest几乎没有关系.它只关心它的数据源而不是页面.

Restuful API设计:假设您的Web请求设计如下:

/ getRecorods?的pageSize = 20&您做生意= 2

这将返回一个JSON数组.除此之外,它还有一个count参数和下一页的链接.这有助于解析和与Web服务器同步.

如何防止API针对相同的行多次触发?

一个简单的标志足以避免加载多个页面.只需确保在主线程中访问该标志.实际的webrequest需要进入后台线程.

下面是您需要放入加载数据的UITableViewController的代码


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    //call http Util here to load the data
    httpUtil.delegate = self;

    //This retrieves post for first page always
    currentPageNumber = 1;
    [httpUtil getRecords:currentPageNumber];

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    int retValue = 0;
    if(recordsArray != nil){
        retValue = [recordsArray count];
    }
    return retValue;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {

    }

    // Configure the cell using recordsArray objectAtIndex

    return cell;
}


- (void)scrollViewDidScroll:(UIScrollView *)scrollView{

      if(self.tableView.contentOffset.y >= (self.tableView.contentSize.height - self.tableView.bounds.size.height)) {

      //NSLog(@" scroll to bottom!");
      if(isPageRefresing == NO){ // no need to worry about threads because this is always on main thread.

        isPageRefresing = YES;
        [self showMBProfressHUDOnView:self.view withText:@"Please wait..."];
        currentpagenumber = currentpagenumber +1;
        [httpUtil getRecords:currentpagenumber];
       }
    }

}

// you can get pageNo from tag
// make sure this is called in main thread
-(void)didFinishRecordsRequest:(NSArray *)results forPage:(NSInteger)pageNo{
    if(pageNo == 1){
        recordsArray = [results mutableCopy];
    }
    else{
        [recordsArray addObjectsFromArray:results];
    }
    isPageRefresing = NO;
    [self.tableView reloadData];
}


-(void)didFailedChalkBoardRequestWithError:(NSError *)error{

    //If Since subsequent refresh calls(for page 2 or page 3 fails)
    //then undo the current page number
    currentpagenumber--;
    isPageRefresing = NO;
}

// HTTP Utility class
-(void)getRecords:(NSInteger)pageNumber{

    NSString *serverUrl = [NSString stringWithFormat:@"http://yourwebsite.com/page/%d /?json",pageNumber];

    NSLog(@"fetching Stories data from server WITH URL %@",serverUrl);
    NSURL *url = [NSURL URLWithString:serverUrl];
    storiesRequest = [ASIHTTPRequest requestWithURL:url];
    storiesRequest.tag = pageNumber;
    [storiesRequest setDelegate:self];
    [storiesRequest startAsynchronous];
}