如何将解码后的分页JSON数据追加到Swift结构体并更新对应字段
解决方案
问题原因
你原来的写法存在逻辑冲突:先往本地的results数组追加新数据,紧接着直接把整个verseSearchResult对象替换成了新页返回的结果,导致之前追加的内容被新页的results直接覆盖。
实现方案
两种实现方式可选,不需要修改原有JSON解码逻辑。
方式1:给结构体扩展合并方法(推荐,复用性更高)
在原有VersesSearchResult结构体中新增合并方法:
struct VersesSearchResult: Decodable { var results: [Verse] var count: Int var next: String? var previous: String? /// 合并新分页的结果 mutating func merge(with newPage: VersesSearchResult) { // 用新页的元数据覆盖旧值 self.count = newPage.count self.next = newPage.next self.previous = newPage.previous // 追加新页的经文数据 self.results.append(contentsOf: newPage.results) } }
修改解码后的赋值逻辑,区分首次加载和后续分页加载:
let verses = try JSONDecoder().decode(VersesSearchResult.self, from: safeData) DispatchQueue.main.async { if self.verseSearchResult == nil { // 首次加载第一页直接赋值 self.verseSearchResult = verses } else { // 加载后续分页,合并数据 self.verseSearchResult?.merge(with: verses) } }
方式2:直接手动合并(不需要修改结构体定义)
如果你不想调整结构体代码,也可以直接在赋值处手动处理:
let verses = try JSONDecoder().decode(VersesSearchResult.self, from: safeData) DispatchQueue.main.async { if self.verseSearchResult == nil { self.verseSearchResult = verses } else { // 手动更新元数据 self.verseSearchResult?.count = verses.count self.verseSearchResult?.next = verses.next self.verseSearchResult?.previous = verses.previous // 追加新页结果 self.verseSearchResult?.results.append(contentsOf: verses.results) } }
补充说明
- 如果接口存在返回重复数据的可能,你可以在追加前根据
Verse的id字段去重,避免列表出现重复条目。 - 下拉刷新场景下,只需要先把
self.verseSearchResult置为nil,再重新加载第一页即可重置数据。
内容的提问来源于stack exchange,提问作者erikvm
相关产品推荐
相关产品推荐

