on 2017-02-28 23:00:00
  • ux
  • marketing
  • events

I was always wondering in how mobile apps manage data displayed by UITableView & UICollectionView by loading more data as scrolling down, in such convenient way when needed ???!!!!. I was also trying to figure out a full comprehensive view from server side as well as from client side to this issue.

Well, so we are here trying to take the burden of this common question, and simplify the answer in such convenient way . Let’s go.


The Scenario :

We will implement a Rest API using PHP Laravel framework (server side) which will return the latests feeds as bulk of data (20 items) in each call. and a swift code to consume the API to load more data as scrolling down.



Server Side :


The API will return bulks of data ex. 20 feeds in descending order for each call respectively. such that the latest 20 feeds for first call, and the next before latest 20 feeds for the second call .. and so on. 


take(20) : To limit the number of results returned from the query to be 20.
skip(0) : to skip a given number of results in the query. such that in the first call skip(0) to don’t skip any feed, and in the second call skip(20) to skip the first 20 feeds and retrieve the next before latest 2o feeds and so on … skip(40), skip(60) … etc.


public function getData($bulk_no)
{ return Feed::orderBy('created_at','desc')->skip($bulk_no)-> take(20)->get();


}

Client Side :


Well, there are many swift-based libraries used to perform HTTP request. one of the best of them is Alamofire. for its simplicity and taking the burden of network tasks and providing user-friendly request/response methods.

The ViewController will implement UITableView and in cellForRowAt delegate method will look like :


var bulk_no = 0
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
.......
if indexPath.row >= bulk_no - 3 {
callFeedAPI()
}
return cell
}


bulk_no : Int var default value= 0. and will have the value of last item; such that after the first call will be updated to 20 and the second call will be 40 and so on …


Call Almofire API Method “callFeedAPI”



func callFeedAPI(){

let feedAPI = FeedAPI() // model FeedAPI

feedAPI.callAPI(completed: {

// code to be executed after completion of API
    self.bulk_no = self.dataArray.count
    self.tableView.reloadData()
   }, delegate : self)
 }
}


after calling API completed :
1. update bulk_no to be the dataArray count ex. 20, 40 , 60 , 80 and etc. 
2. reload UITableView data.


class FeedAPI{

func callAPI (completed : @escaping DownloadComplete, delegate : ViewController){
  let URL = URL(string: "URL/\(delegate.lastId)")
  Alamofire.request(URL!).responseJSON { response in
    switch response.result {
     case .success:
        if let resultDictionary = response.value as? Dictionary{
        if let data = resultDictionary["data"] as?  Dictionary  {
          for obj in data {
           if let item = resultDictionary["data"] as? String{
               delegate.dataArray.append(item)
        }
       }
      }
     }
 
    break 
    case .failure(let error):
      print(error)
}
completed()
 }
}
}


here in FeedAPI model execute callAPI method which call Rest API URL and appending bulk_no to skip # items as we mentioned in the server side.


// Server Side

public function getData($bulk_no)
{
return Feed::orderBy('created_at','desc')->skip($bulk_no)-> take(20)->get();  
 

}

after successfully feeds returned from server with success status : append the ViewController dataArray with the new bulk data. and completed() escaping closure will return to the.


We had a nice trip from Server to client … Awesome? That’s it.