0

I would like to load data from the server upon scrolling down to index 5 within a page (i.e. 5, 15, 25, etc) in the background in order to make it appear the tableview is scrolling continuously without freezing the UI. I tried the method below to load the next page if the index is a multiple of 5 and not even, but I'm finding it's not working effectively.

Below you can see how I try to load more data once we reach a specific index.

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

   if indexPath.row % 2 != 0 && indexPath.row % 5 == 0 {
                currentPgNum = currentPgNum! + 1
                    self.loadMore()
   }

}

Below you can see my request to the server to load more data.

  func loadMore () {

        guard !self.reachedEndOfItems else {
            return
        }

        self.offset = self.offset! + 10
        print("load more offset: \(self.offset)")

        var start = 0
        var end = 0


        isPullToRefresh = false

        let userCreds = UserDefaults.standard

        var getReqString = ""


        if userCreds.bool(forKey: "client_journal") == true || userCreds.bool(forKey: "user_journal") == true {

            var pageNum = ""
            if let pgNum = currentPgNum {
                print(pgNum)
                pageNum = String(pgNum)
            }
            var filterEntryType = ""
            if let entryTypeStr = filtEntryType {
                filterEntryType = entryTypeStr
            }

            var filterUserId = ""
            if let userId = filtUserId {
                filterUserId = userId

            }

            getReqString = "https://gethealthie.com/selected_entries.json?page=\(pageNum)&user_id=\(filterUserId)&entry_type=\(filterEntryType)&entry_filter="


        } else {

            if let pgNum = currentPgNum {
                print(pgNum)

                getReqString = "https://gethealthie.com/entries.json?page=\(pgNum)"
            }

        }

        DispatchQueue.global(qos: .background).async {
            BXProgressHUD.showHUDAddedTo(self.view)
            let request = Alamofire.request(getReqString, method: .get, headers: [
                "access-token": userCreds.object(forKey: "access-token")! as! String,
                "client": userCreds.object(forKey: "client")! as! String,
                "token-type": userCreds.object(forKey: "token-type")! as! String,
                "uid": userCreds.object(forKey: "uid")! as! String,
                "expiry": userCreds.object(forKey: "expiry")! as! String
                ]).responseJSON { (response:DataResponse<Any>) in
                    print(response.response)

                    let json = JSON(data: response.data!)
                    print(json)

                    print("yes")
                    print(json.count)


                    if userCreds.bool(forKey: "client_journal") == true || userCreds.bool(forKey: "user_journal") == true {
                        self.totalEntries = json["entries"].count

                        let totalEntryCount = json["entries"].count
                        start = 0
                        end = totalEntryCount
                    } else {
                        self.totalEntries = json["entries"].count

                        let totalEntryCount = json["entries"].count
                        start = 0
                        end = totalEntryCount
                    }

                    if  self.totalEntries == 0 {
                        BXProgressHUD.hideHUDForView(self.view);

                    } else if end <= self.totalEntries {
                        var jourIdx = 0

                        let newPatient = Patient()
                        let newDietitian = Dietitian()


                        for i in start ..< end {


                            let allEntries = json["entries"]
                            print(allEntries)
                            print("Entry count in loadMore is \(allEntries.count)")

                            let entry = allEntries[i]
                            print(entry)

                            let category = entry["category"]
                            print(category)


                            let name = entry["entry_comments"]
                            let k = name["id"]


                            var indexStr = String(i)

                            //entry attributes
                            self.jsonIdx.add(indexStr)

                            self.type.add(entry["type"].stringValue)
                            self.desc.add(entry["description"].stringValue)
                            self.category.add(entry["category"].stringValue)
                            //food cell- metric stat == healthy int
                            self.metric_stat.add(entry["metric_stat"].stringValue)
                            self.dateCreate.add(entry["created_at"].stringValue)
                            self.viewed.add(entry["viewed"].stringValue)
                            self.seenStatusArr.add(entry["viewed"].stringValue)
                            self.comments.add(entry["entry_comments"].rawValue)
                            self.entryType.add(entry["category"].stringValue)
                            //   "category" : entryType as AnyObject]

                            let posterInfo = entry["poster"]
                            let first = posterInfo["first_name"].stringValue
                            let last = posterInfo["last_name"].stringValue
                            let full = first + " " + last
                            self.captionName.add(full)


                            //food cell subcat
                            self.hungerInt.add(entry["percieved_hungriness"].stringValue)
                            self.prehunger.add(entry["ed_prehunger_string"].stringValue)
                            self.posthunger.add(entry["ed_posthunger_string"].stringValue)
                            self.emotions.add(entry["emotions_string"].stringValue)
                            self.reflection.add(entry["reflection"].stringValue)


                            print(self.comments)
                            self.id.add(entry["id"].stringValue)
                            self.entryImages.add(entry["image_url"].stringValue)


                            if i == end - 1 {
                                userCreds.set(json.count, forKey: "oldJsonCount")

                                DispatchQueue.main.async {
                                    self.tableView.reloadData()

                                    BXProgressHUD.hideHUDForView(self.view)

                                }
                            }

                        }


                    } else {
                        var reachedEndOfItems = true
                        BXProgressHUD.hideHUDForView(self.view);
                        print("reached the end")
                    }
            }
        }

Any ideas?

mir
  • 183
  • 1
  • 12
  • It looks like you're modifying the UI from a background thread. I think you'll need to add / remove your HUD from the main thread. – toddg Jan 07 '17 at 18:00
  • 1
    Alamofire methods are asynchronous. Why are you adding it in a global thread? Everything should work fine if you remove the dispatch block. Also, seems like you're doing UI updation in background thread. – ebby94 Jan 07 '17 at 18:04
  • @toddg How do you suggest I update UI on the main thread? I referred to this post for updating UI http://stackoverflow.com/questions/26743367/updating-the-ui-using-dispatch-async-in-swift. – mir Jan 07 '17 at 21:56
  • @ebby94 Also, does the method above seem like the correct way of loading entries once a user scrolls to a specific index? Thank you both! – mir Jan 07 '17 at 21:59

0 Answers0