ios - Swift 4:使用数组中的数据进行分页以在用户滚动时调用 API
问题描述
背景
在我的应用程序中,我存储了一堆对象 ID。我使用这些 ID 进行批量 API 调用。API 将每次调用限制为 10 个 ID 号。此数据在 UITableView 上呈现。用户可以添加和删除对象,这会在数据库中添加或删除对象 ID。
我正在使用 Firestore 数据库来存储对象 ID。
当前实施
这是我迄今为止实现的,但是在添加和删除对象时它会使应用程序崩溃。我无法弄清楚如何正确处理这些情况以及这是否是做这种事情的正确模式。
- 获取用于进行 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()
}
- 获取对象 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
}
}
在 UITableView 单元格上渲染数据
使用以下方法从 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
}
}
}
}
添加或删除对象:
- 在 Firestore 数据库中添加或删除对象 ID
- 清除objectIds、chunkedObjectIds、offset和objects
- 侦听器触发读取数据并重复该过程
问题与问题
这可以很好地加载初始数据。但是添加时会发生重复(有时会崩溃)。删除应用程序时会因为超出范围异常而崩溃。
这是首先使用的正确模式吗?如果是这样,我在第一次加载后处理案例时缺少什么,特别是新对象 ID 的添加和删除。
编辑
我已经根据评论中的反馈更改了实现。所以现在,流程是这样的:
- 设置侦听器以从 Firestore 获取数据
- 循环遍历 Firestore 中的对象 id,当计数器小于 10 或者我们到达 object.count - 现在我保存下一个偏移量,下次它触发此方法时,我使用相同的 while 条件从下一个偏移量启动一个循环
- 从 3rd 方 API 获取对象
- 我一直使用
willDisplay cell
方法来触发更多数据加载——它似乎比scrollDidEnd
方法更可靠。
所以现在应用程序不再崩溃了。firestore 监听器存在一些问题,但我将把它作为一个单独的问题发布。
解决方案
推荐阅读
- react-native - 键盘在外部触摸时被关闭,并且 onPress() 首次无法正常工作
- python - Python上的左连接
- c# - 如何获取以我的表单为父级的窗口的当前标题?
- java - Checkstyle 无法满足抑制过滤器,这是为什么呢?
- javascript - 加快javascript游戏的线索播放
- java - Google Protobuf 验证错误
- java - 如何创建一个程序来读取 JAVA 中的 .diff 或 .patch 文件?
- css - AEM 6.5 版,是否可以合并类?
- javascript - Spring Security 拒绝提供静态内容(Javascript 文件)
- typescript - 如何为 TypeScript 中的单个变量分配不同的接口?