web-dev-qa-db-ja.com

iOS-テーブルビューにページ分割されたAPI出力を使用させる方法は?

私が書いているAPIには約2000レコードがあり、私が書いた単純なRESTful APIを介してJSONで返されます。

大量のデータに関する問題を減らすために、ページネーションを使用して、offsetまたはlimitまたはpageなどのリクエストごとに最初の10または最初の20だけを返すようにします、など.

しかし、私の質問は、結果の次のページを取得するタイミングをiOS UITableViewがどのようにして知るのかということです。

私はこれをどのように行うか本当にわかりません。ユーザーが超高速でスクロールしている可能性があるため、APIが一度に20または50レコードを取得するのに十分な時間がない可能性があります。

これに関連する別の問題は、ユーザーがUITableViewを下にスクロールし、次に上にスクロールしてから再び下にスクロールするとします。同じ行に対してAPIが複数回起動されないようにするにはどうすればよいですか。

ありがとう

22
zardon

あなたはMVCに関して考えていないようです。 UITableViewは、ページングとWebリクエストとはほとんど関係がありません。それは、ページではなくデータソースを気にしているだけです。

Restuful APIの設計:Webリクエストが次のように設計されていると想定します。

/ getRecorods?pageSize = 20&pageNo = 2

これにより、JSONの配列が返されます。それに加えて、カウントパラメータと次のページへのリンクがあると便利です。これは、Webサーバーとの解析および同期に役立ちます。

同じ行に対してAPIが複数回起動されないようにするにはどうすればよいですか?

複数のページのロードを回避するには、単純なフラグで十分です。フラグがメインスレッドでアクセスされていることを確認してください。実際のWebリクエストはバックグラウンドスレッドで送信する必要があります。

以下は、データをロードするUITableViewControllerに配置する必要があるコードです

 
-(void)viewDidLoad 
 {
 [super viewDidLoad]; 
 //ビューをロードした後、通常はnib。
 
 //ここでhttp Utilを呼び出してデータをロードします
 httpUtil.delegate = self; 
 
 //これは最初に投稿を取得します常にページ
 currentPageNumber = 1; 
 [httpUtil getRecords:currentPageNumber]; 
 
} 
 
-(NSInteger)tableView: (UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
 {
 //セクションの行数を返します。
 int retValue = 0; 
 if( recordsArray!= nil){
 retValue = [recordsArray count]; 
} 
 return retValue; 
} 
 
-( UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
 {
 static NSString * CellIdentifier = @ "Cell"; 
 
 CustomCell *セル= [tableView dequeueReusableC ellWithIdentifier:CellIdentifier]; 
 if(cell == nil){
 
} 
 
 // recordsArray objectAtIndex [.____を使用してセルを構成します。] 
 return cell; 
} 
 
 
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
 
 if(self.tableView.contentOffset.y> =(self.tableView.contentSize.height-self.tableView.bounds.size.height)){
 
 // NSLog(@ "下にスクロール!"); 
 if(isPageRefresing == NO){//これは常にメインスレッド上にあるため、スレッドについて心配する必要はありません。
 
 isPageRefresing = YES ; 
 [self showMBProfressHUDOnView:self.view withText:@ "お待ちください..."]; 
 currentpagenumber = currentpagenumber +1; 
 [httpUtil getRecords:currentpagenumber]; 
} 
} 
 
} 
 
 //タグからpageNoを取得できます
 //これがメインスレッドで呼び出されます
-(void)didFinishRecordsReques t:(NSArray *)results forPage:(NSInteger)pageNo {
 if(pageNo == 1){
 recordsArray = [results mutableCopy]; 
} 
 else {
 [recordsArray addObjectsFromArray:results]; 
} 
 isPageRefresing = NO; 
 [self.tableView reloadData]; 
} 
 
 
-(void)didFailedChalkBoardRequestWithError:(NSError *)error {
 
 //以降のリフレッシュ呼び出し以降(ページ2またはページ3が失敗した場合) 
 //現在のページ番号を元に戻します
 currentpagenumber-; 
 isPageRefresing = NO; 
} 
 
 // HTTPユーティリティクラス
-(void)getRecords:(NSInteger)pageNumber {
 
 NSString * serverUrl = [NSString stringWithFormat:@ "http://yourwebsite.com/page/%d /?json",pageNumber];

 NSLog(@ "URLを使用してサーバーからストーリーデータを取得%@"、serverUrl); 
 NSURL * url = [NSURL URLWithString:serverUrl ]; 
 storiesRequest = [ASIHTTPRequest reque stWithURL:url]; 
 storiesRequest.tag = pageNumber; 
 [storiesRequest setDelegate:self]; 
 [storiesRequest startAsynchronous]; 
} 
 
21
Kunal Balani

Swiftの場合

func scrollViewDidScroll(scrollView: UIScrollView) {
        if collectionViewGif.contentOffset.y >= self.collectionViewGif.contentSize.height - self.collectionViewGif.frame.size.height
        {
            offset = offset + 1
            self.fetchGifWithPaination(defaultText)
        }
    }
0