0

I am implementing showing post part, I want it to do pagination, I got Query part. What I understand is I set limited number of posts when user reached last post that updated in tableView, query fetches more objects by next set limit.

For these, I need something indicates when tableView indexPath is reached at last one or before last one.

I searched some, I think this is good one, but I don't know what does mean.

Get notified when UITableView has finished asking for data?

Could anyone explain me what does mean(how it works) and how to subclass in UITableView's reloadData for this?

fun reloadData() {
print("begin reload")
super.reloadData()
print("end reload")
}

I add my fetching code, I don't think it is working.

var limit = 10
var skip = 0
func fetchAllObjectsFromParse() {

    //empty postArray
    postsArray = []

    //bring data from parse
    let query = PFQuery(className: "Posts")
    query.limit = limit

    query.orderByDescending("createdAt")
    query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error) -> Void in
        if error == nil && objects != nil{
            for object in objects! {

                self.postsArray.append(object)
                                }

                if (objects!.count == self.limit){

                    let query = PFQuery(className: "Posts")
                    self.skip += self.limit
                    query.skip = self.skip
                    query.limit = self.limit
                    print(self.limit)
                    print(self.skip)
                    query.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
                        if error == nil && objects != nil {
                            for object in objects! {
                                self.postsArray.append(object)
                                print(objects?.count)
                            }
                        }
                    })



                    dispatch_async(dispatch_get_main_queue(),{
                        self.tableView.reloadData()
                    })
                }

        }else{
            print(error?.localizedDescription)


        }
    }
}
Community
  • 1
  • 1
Janghyup Lee
  • 167
  • 3
  • 17
  • Are you trying to build paginated networking? Or rather do you just want to know when the user scrolls to the end of the table view so you can load more results (which is essentially pagination) – barndog Nov 01 '15 at 01:31
  • I am doing first one, So I am looking for the essentially pagination function. if you explain me both, that would be the best. I add my fetch code here, I don't think it is working. – Janghyup Lee Nov 01 '15 at 01:49

1 Answers1

0

First let's tackle pagination. Now pagination isn't undoable but it does require your server to accept pages so that it knows which set of results to return. For example if you have 100 results in group sizes of twenty, in your url request you'd have to specify if you wanted page 0 - 4.

I would personally recommend using an open-source library to take care of pagination for you. Take a look at MMRecord, it does have some pagination support for you. If you are feeling ambitious and you want to implement it on your own, you'll need to build some networking service, best built on something like AFNetworking that keeps track of the last requested page.

In swift, that would look something like this:

NetworkManager.GET('http://someURI', parameters: [:], page: 0)

Somehow you have to keep the state of which page is next around. A better design, as suggested here, is to use protocols and some sort of datasource wrapper that abstracts the mechanism from the client.

Now you also asked how to detect when a table view scrolls to the end so you can fire off a network request. One way to do it is simple observe scrollViewDidScroll (UITableView inherits from UIScrollView) and check to see if the contentOffset is >= self.tableView.contentSize - self.tableView.frame.size.height (which will be the content offset of when the table is all the way scrolled). However you want the user of your application to be able to keep scrolling without having to scroll to the bottom, waiting for it to load, then continue scrolling so what I would is fire the request when they've scrolled 3/4 down the page or even halfway if you know the request will take a long time. That way by the time they get to the bottom, it'll already have loaded the data and the user will never know the difference.

EDIT:

I would add a few suggestions for you apart from my answer. 1) Take a look at this: http://artsy.github.io/blog/2015/09/24/mvvm-in-swift/

It talks about the MVVM design pattern which is much better for holding state instead of having state variables in your view controller.

2) your function, fetchAllObjectsFromParse is a bad name for a couple of reasons. First, the name implies that the function fetches all the objects at once, which isn't the case if you want it paginated.

Maybe something like this:

func fetchObjectsForModel(model: String, atPage page: Int, withBlock block: ([PFObejct], NSError?) -> Void {

}

And then make another function which will generate your query:

func generateQueryWithSkips(skip: Int, limit: Int) -> PFQuery {}
barndog
  • 6,975
  • 8
  • 53
  • 105
  • I would try that when user reaches half of tableView, then fetches next 25 data. I gotta make this by tmr, Do you think that is tough for beginner? – Janghyup Lee Nov 01 '15 at 02:29
  • It's not impossible but I would personally take my time and design the architecture in such a way that everything is encapsulated and whatnot. Would you mind accepting the answer if it works for you? – barndog Nov 01 '15 at 02:38