Swift 4:使用数组中的数据进行分页,以便在用户滚动时进行 API 调用

2024-02-11

背景

在我的应用程序中,我存储了一堆对象 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. 获取对象 Ids 数组,分成数组数组(共 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 和对象被清除
    • 监听器触发数据读取并重复该过程

问题与问题

这对于加载初始数据非常有效。但是添加时会发生重复(有时会崩溃)。删除时应用程序会因超出范围异常而崩溃。

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

Edit

我根据评论中的反馈更改了实现。那么现在,流程是这样的:

  1. 设置侦听器以从 Firestore 获取数据
  2. 循环访问 Firestore 中的对象 id,当计数器
  3. 从第 3 方 API 获取对象
  4. 我一直用willDisplay cell触发更多数据加载的方法 - 它似乎比scrollDidEnd method.

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


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Swift 4:使用数组中的数据进行分页,以便在用户滚动时进行 API 调用 的相关文章

  • 重新定位时 Mapbox 默认的 compassView 会给出奇怪的结果

    我遇到一种情况 必须将地图框罗盘视图重新定位到不同的位置 当我以其他点作为其 compassView 轴旋转地图时 compassView 现在正在旋转 并给了我一个奇怪的结果 附截图 黑色mapBox默认罗盘图标是旋转的 参考截图 这是
  • 切换到 Xcode 7 后,应用程序大小从 9 MB 增长到 60 MB,有解决办法吗?

    我一直在回顾 Git 历史来寻找文件大小发生巨大变化的原因 但我能找到的唯一真正原因是从 Xcode 6 切换到 Xcode 7 GM 我发现这些是文件大小贡献最大的 10 个 ipa创建自Archive操作在一个Release构建配置 u
  • 新的 iTunes 连接界面错误“您必须选择一个版本”

    当尝试将我的新应用程序提交到应用程序商店时 我注意到苹果已经更改了其网站界面 更新元数据和关键字并点击 提交审核 后 我收到错误 您必须选择一个版本 通过谷歌搜索 我没有找到答案 但是 我注意到 构建 标题旁边有一个加号按钮 您必须在其中选
  • Swift 3 GCD API 更改后的dispatch_once

    新语法是什么dispatch once在语言版本 3 中进行更改后的 Swift 中 旧版本如下 var token dispatch once t 0 func test dispatch once token These 对 libdi
  • 有没有办法以编程方式选择 Segue 锚点?

    假设我有一个 Storyboard 其中包含一个包含按钮的视图 当用户按下此按钮时 会出现一个弹出窗口 因此 我需要使用 Xcode 将 Segue 拖动到按钮来设置锚点 然后执行使用标识符执行Segue 所以 我的问题是 有没有办法以编程
  • 排除 Realm 模型类

    我的应用程序中配置了两个领域文件 我想存储我的Log将模型与其他模型分开保存为单独的文件 我的问题是我也看到了我的Log我不想要的默认 Realm 文件中的模型类 如何从给定的 Realm 文件中排除特定的模型类 我使用主 Realm 文件
  • Swift 3/4 dash 转驼峰式 (Snake 转驼峰式)

    我正在尝试执行一个简单的破折号到驼峰案例 在 swift 3 或 4 中 this is my id 将变成 thisIsMyId 无论我做什么 我都找不到足够优雅的方法来做到这一点 以下不起作用 str split separator e
  • Javascript 无法正确排序 DECIMAL 数字

    我有一些代码可以按字母顺序对名称进行排序 我遇到的问题是它处理小数的方式 它对名称进行排序 如下所示 我宁愿它按数字递增 DOG 1 0510 DOG 1 1031 DOG 11 1792 DOG 12 0920 DOG 12 1170 D
  • Angular/ HTML5 到 iOS WKWebView 通信

    我们正在尝试看看发送信号的最佳选择是什么To iOS WKWebView fromAngular 6 HTML5 项目 任何示例都会很棒 我们想要做的是 我们在 Angular 网页上有一个按钮 单击该按钮应该通知 iOS 执行某些操作 我
  • iOS 上的三字母国家代码

    我知道您可以在 iOS 上获取所有国家 地区的两个字母的国家 地区代码 但是有没有办法获得三个字母的国家代码 So from http en wikipedia org wiki ISO 3166 1 alpha 2 http en wik
  • 如何更改某些功能以兼容 iOS 10 或更低版本的 Snapchat 中的某些功能,例如相机视图控制器

    我正在制作一个视图控制器来制作像 snapchat 相机一样的相机视图控制器 我下面的代码在 iOS 11 或更高版本上完美运行 老实说 我并没有真正掌握我的代码 因为我只是按照这个像相机视图控制器这样的 snapchat 的教程进行操作
  • 从钥匙串保存和加载 |斯威夫特[重复]

    这个问题在这里已经有答案了 如何简单地将字符串存储在钥匙串中并在需要时加载 有几种SO解决方案 主要参考Git repo 但我需要最新 Swift 上最小和最简单的解决方案 当然 我不想添加 git 框架来简单地在我的项目中存储密码 有类似
  • 无法将 (Timer!) -> Void 转换为 ((CFRunLoopTimer?) -> Void)! - 将 NSTimer 扩展转换为 Swift 3

    我正在尝试将我在项目中使用的 Pod 转换为 Swift 3 它不是我编写的 但原作者尚未更新它 所以我将它分叉为我自己尝试的任何内容 但 我在尝试将扩展名转换为NSTimer到斯威夫特 3 Cannot convert value of
  • 如何通过Grape API获取路由

    我使用 gem grape 作为 api 我尝试通过命令获取 api urlrake grape routes namespace grape do desc routes task routes gt environment do API
  • Xcode - 免费清除设备文件夹?

    我正在删除一些文件夹和文件 以便在驱动器上腾出更多空间 我知道在路径中 Library Developer CoreSimulator Devices 每个模拟器和每个版本都有文件夹 这个文件夹对我来说大约有 11GB 大小 我知道我可以删
  • iOS 9.3 出现新的 UIPDFPageRenderOperation 错误?

    我正在向 UIWebView 添加一些 PDF 链接 每次加载并做出滚动手势时 都会收到此错误 objc 910 UIPDFPageRenderOperation 对象 0x14acaca10 过度释放 当已经解除分配时 打断 objc o
  • iOS 上邮件到达时收到通知吗?

    当邮件到达标准邮件应用程序时 有没有办法让应用程序收到通知 更准确地说 我想编写一个应用程序 它能够从标准邮件应用程序读取传入的电子邮件 其中包含自定义 txt 格式的新联系人或事件 然后 应用程序应将此新联系人 事件添加到 ipad 反之
  • 快速从 appDelegate 中 popToRootViewController

    我试图从应用程序委托弹出到导航堆栈的根视图控制器 并且在将 obj c 中的内容转换为 swift 时遇到一些问题 obj c 中的工作原理 UINavigationController navigationController UINav
  • geocoder.geocodeAddressString 今天不再适用于快速更新

    https developer apple com library prerelease mac releasenotes General APIDiffsMacOSX10 11 Swift CoreLocation html https
  • REST API 路由最佳实践

    我想知道当订单是一种资源时 为以下场景创建 REST API 的最佳实践是什么 获取数据库中的所有订单 当然不是实际场景 仅供理解 通过订单ID获取订单 根据订单ID获取单个订单 单个 GET 路由是否可以用于所有这些场景 或者我们应该针对

随机推荐

  • 如何在一定时间后重试功能请求

    如果用户数据为空 如何让它重试发送尝试 最多重试 2 次 10 秒后重试 1 次 public class UserHandler private List users new ArrayList public void addUser u
  • 绕过 requiredfieldvalidator

    我有一个网络表单 上面有验证器 当用户按下提交按钮时 验证器可以很好地工作 但是 当用户按下注销按钮时 验证器会停止该按钮的工作 关于如何解决这个问题有什么建议吗 您需要使用CausesValidation按钮上的属性
  • nf_conntrack_helper注册未注册端口返回错误

    我有以下代码从内核 3 18 取消注册和注册 sip conntrack static void nf conntrack sip fini void int i j for i 0 i lt ports c i for j 0 j lt
  • 在没有 gitosis/gitolite 的情况下通过 SSH 运行“安全”git 服务器?

    是否可以通过 ssh 运行 git 服务器 使用authorized keys and command 限制仅访问 git 存储库 而不使用 gitosis gitolite 是的 分配git shell http www kernel o
  • 获取 Youtube 数据 API 的 403 禁止错误

    我在对 YouTube 数据 API 进行 API 调用时收到 403 禁止错误 我尝试生成不同类型的密钥 Web 浏览器 服务器等 钥匙不受限制 我尝试从服务器和 Chrome 的邮递员拨打电话 请求 URL 和响应如下 https ww
  • 访问 AVRO GenericRecord (Java/Scala) 中的嵌套字段

    我有一个带有嵌套字段的 GenericRecord 当我使用genericRecord get 1 它返回一个包含嵌套 AVRO 数据的对象 我希望能够像这样访问该对象genericRecord get 1 get 0 但我不能 因为 AV
  • 在 woocommerce 中隐藏折扣信息而不取消优惠券

    我在 Woocommerce 购物车中使用优惠券进行计算 它会自动为总额添加折扣 以便可以将正确的金额发送到支付网关 我想向访客隐藏有关此优惠券 折扣的所有信息 Problem 我发现的唯一方法 见下文 隐藏优惠券字段 行 总计 和消息 但
  • COBOL:GDG 文件描述符 (FD) 可以引用多代吗?

    我有一个程序可以读取 GDG 文件并将数据移动到工作存储 我很想知道是否可以使用对文件定义的引用对多代 GDG 重复此过程 也许有一种方法可以在文件定义上使用下标 我的想法是必须有一种方法将不同的文件定义移动到引用变量中以访问文件 基于建议
  • 如何检测设备是否支持鼠标?

    我目前使用以下测试 取自 Modernizr 来检测触摸支持 function is touch device var bool if ontouchstart in window window DocumentTouch document
  • 我的树形图的 Arangodb 自定义过滤器/访问者

    我有一个带有两个边定义的图 如下所示 isDepartment organisation gt organisation hasAccess user gt organisation 组织嵌套在树中 无循环 有多个顶级组织 没有任何传入is
  • 使用 shell 脚本从 sql 脚本中选择列到局部变量中

    如何将从表中检索到的列值存储到 shell 脚本中的变量中 我有以下代码 usr bin ksh echo This script will try to connect to sql plus and displays the date
  • 为什么在释放指针后取消引用它时会得到不同的结果?

    我有一个关于 C 内存管理的问题 以及 Debian GNU Linux 下的 GCC 4 3 3 根据 K R 的 C 编程语言书籍 第 7 8 5 章 当我释放指针然后取消引用它时 会出现错误 但我有一些疑问 因为我注意到有时 正如我在
  • 在 Flask 中,设置 cookie,然后重定向用户

    看起来在 Flask 中 cookie 是通过直接修改响应对象来设置的 如何返回响应对象 同时在成功登录后将用户重定向到不同的页面 我想专门重定向用户而不是呈现不同的页面 以防用户点击刷新 这是我当前的代码 它仅显示同一页面 login h
  • popen()/fgets() 间歇性返回不完整的输出

    我遇到了一个奇怪的问题popen and fgetsLinux系统上的库函数 演示该问题的简短程序如下 安装信号处理程序SIGUSR1 创建辅助线程来重复发送SIGUSR1到主线程 在主线程中 通过以下方式重复执行一个非常简单的 shell
  • rsync 无法解释的错误(代码 129)

    我正在尝试将数据从一台服务器 rsync 到另一台服务器 大约有大约 1 1T 的数据 但是当我进行 rsync 时 我在传输过程中遇到以下异常 从而终止了进程 rsync 错误 rsync c 541 sender 3 0 7 出现无法解
  • uint8 的冗余转换不适用于 GCC 4.8.1

    我有一些遗留代码 通常是使用 GCC 3 4 4 为 PowerPC 编译的 现在我正在移植一些我想用 MinGW 的 GCC 4 8 1 编译的代码部分 在代码中的某个时刻我发现了这一点 Prototypes void foo uint8
  • 如何在不使用全局或会话变量的情况下重用查询结果以更快地导出到 csv 和 xls

    我有一个功能 最初以 HTML 报告 显示结果 然后 可以导出为 CSV 和 XLS 这个想法是重用用于呈现 HTML 的查询的结果 导出相同的记录 而无需再次重新运行查询 最接近的实现是这样的 将结果存储在全局变量 last consul
  • 如何在不移动 X、Y 位置的情况下缩放视图?

    我有一个RadioGroup我正在尝试缩小规模 因为它太大了 所以我用setScaleX and setScaleY 并将其缩小 它可以工作 但问题是当我缩放视图时 视图会改变 X 和 Y 位置 我希望它在缩放后保持相同的左上角坐标 如何让
  • 检查数字中是否有“数字”零的最快方法?

    检查数字中是否包含数字 0 的最快方法是什么 我需要开发一种快速方法 因为我必须在 20 美元秒内对接近 10 9 美元的数字执行这些检查 将其转换为字符串后搜索零是否有效 除以 2 的幂以外的数字 无论数字是多少 都将执行相同次数的运算
  • Swift 4:使用数组中的数据进行分页,以便在用户滚动时进行 API 调用

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