首页 > 解决方案 > Swift 4:使用数组中的数据进行分页以在用户滚动时调用 API

问题描述

背景

在我的应用程序中,我存储了一堆对象 ID。我使用这些 ID 进行批量 API 调用。API 将每次调用限制为 10 个 ID 号。此数据在 UITableView 上呈现。用户可以添加和删除对象,这会在数据库中添加或删除对象 ID。

我正在使用 Firestore 数据库来存储对象 ID。

当前实施

这是我迄今为止实现的,但是在添加和删除对象时它会使应用程序崩溃。我无法弄清楚如何正确处理这些情况以及这是否是做这种事情的正确模式。

  1. 获取用于进行 API 调用的对象 ID
var objectIds: [String] = []
var chunkedObjectIds: [[String]] = []
var objects: [Array] = []
var offset: Int = 0

override func viewDidLoad() {
    super.viewDidload()

    getObjectIds()

 }

func getObjectIds() {
    // get objects IDs and store then in objectIds from the Firestore database
    // setup the .addSnapshotLister so the query is triggered whenever there is a change in the data on Firestore for the collection

    return chunkedObjectIds

    // when finished, get the first 10 objects from the 3rd party API

    fetchObjects()

}
  1. 获取对象 ID 数组,拆分为数组数组(很多 10 个)& 对前 10 个进行 API 调用
func fetchObjects() {

     // split objectIds array in array of arrays, in lots of 10
     // chunkedObjectIds is set here

     // request the objects for the first 10 ID numbers

    Alamofire.request(… parameter with first 10 object ids …) (objects) in {

        // save objects

        // increment the offset
        offset += 1
    }

}
  1. 在 UITableView 单元格上渲染数据

  2. 使用以下方法从 3rd 方 API 加载更多数据:

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

        let lastRow = objects.count 

        var parameters = [String: Any]()

        if indexPath.row == lastRow {
            if !(offset == self.chunkedObjectIds.count) {

                // process the next batch from the array
                parameters["id-numbers"] = self.chunkedObjectIds[offset].map{String($0)}.joined(separator: ",")

                Alamofire.request(… paramaters: parameters) { (objects) in
                    for item in 0..<objects.count {
                        let indexPath = IndexPath(row: item + self.objects.count, section: 0)
                        self.paths.append(indexPath)
                    }
                    self.objects.append(contentsOf: objects)
                    self.tableView.beginUpdates()
                    self.tableView.insertRows(at: self.paths, with: .automatic)
                    self.tableView.endUpdates()
                    self.paths.removeAll()
                    self.offset += 1
                }
            }
        }
    }
  1. 添加或删除对象:

    • 在 Firestore 数据库中添加或删除对象 ID
    • 清除objectIds、chunkedObjectIds、offset和objects
    • 侦听器触发读取数据并重复该过程

问题与问题

这可以很好地加载初始数据。但是添加时会发生重复(有时会崩溃)。删除应用程序时会因为超出范围异常而崩溃。

这是首先使用的正确模式吗?如果是这样,我在第一次加载后处理案例时缺少什么,特别是新对象 ID 的添加和删除。

编辑

我已经根据评论中的反馈更改了实现。所以现在,流程是这样的:

  1. 设置侦听器以从 Firestore 获取数据
  2. 循环遍历 Firestore 中的对象 id,当计数器小于 10 或者我们到达 object.count - 现在我保存下一个偏移量,下次它触发此方法时,我使用相同的 while 条件从下一个偏移量启动一个循环
  3. 从 3rd 方 API 获取对象
  4. 我一直使用willDisplay cell方法来触发更多数据加载——它似乎比scrollDidEnd方法更可靠。

所以现在应用程序不再崩溃了。firestore 监听器存在一些问题,但我将把它作为一个单独的问题发布。

标签: iosarraysswiftapiuitableview

解决方案


推荐阅读