作为一个Swift新手,我尝试获取一个JSON对象列表,将它们保存到Core Data,然后在SwiftUI列表中显示:
x1c 0d1x的数据
JSON对象有一个唯一的数字uid
(在我的PostgreSQL后端中充当主键)。
我将它们Map到TopModel.swift中的id
:
struct Top: Codable, Identifiable {
var id: Int { uid }
let uid: Int
let elo: Int
let given: String
let photo: String?
let motto: String?
let avg_score: Double?
let avg_time: String?
}
字符串
然后我有一个singleton DownloadManager.swift,它下载JSON列表并将对象存储到Core Data中:
func getTopsCombine() {
guard let url = URL(string: "https://wordsbyfarber.com/ru/top-all") else { return }
URLSession.shared.dataTaskPublisher(for: url)
.subscribe(on: DispatchQueue.global(qos: .background))
.receive(on: DispatchQueue.main)
.tryMap(handleOutput)
.decode(type: TopResponse.self, decoder: JSONDecoder())
.sink{ ( completion ) in
print(completion)
} receiveValue: { [weak self] (returnedTops) in
for top in returnedTops.data {
print(top)
let topEntity = TopEntity(context: PersistenceController.shared.container.viewContext)
topEntity.uid = Int32(top.id)
topEntity.elo = Int32(top.elo)
topEntity.given = top.given
topEntity.motto = top.motto
topEntity.photo = top.photo
topEntity.avg_score = top.avg_score ?? 0.0
topEntity.avg_time = top.avg_time
}
self?.save()
}
.store(in: &cancellables)
}
型
不幸的是,这会导致在Core Data中保存多个相同的记录(如您在上面的屏幕截图中所见)。
这里的标准iOS解决方案是什么?
如何实现唯一性(在我最初的Android/Room应用中,我使用@PrimaryKey public int uid;
)?我在Xcode中没有看到这样的选项:
的
以及如何合并JSON对象的提取列表(在我的Android应用中,我使用DiffUtils)?
2条答案
按热度按时间lf5gs5x21#
在Core Data中,您必须检查条目是否已经存在,创建一个 predicate 并获取具有唯一ID的对象。如果没有项目,则创建一个。
字符串
您甚至可以更新项(如果它存在)
型
xkrw2x1b2#
如果您没有使用CloudKit,则可以对Core Data实施唯一约束。如果你是,你将不得不根据身份证自己进行比较。
对于使用唯一约束,您只需将它们添加到受约束实体的数据模型检查器的“约束”部分。请注意,此图像显示了检查器的前一个图标,但它仍然是最右边的图标:
的数据
如果您计划使用CloudKit,则不能使用约束,因为CloudKit中不允许使用约束。因此,您需要编写一个函数来唯一化数据,并在数据写入存储后调用该函数。这听起来像是因为你是跨平台,所以你不会使用CloudKit,所以上面的方法应该可以正常工作。