核心数据 - 再次获取 JSON 时,收藏的帖子变得重复
Posted
技术标签:
【中文标题】核心数据 - 再次获取 JSON 时,收藏的帖子变得重复【英文标题】:Core Data - Favorited posts become duplicate when fetching JSON again 【发布时间】:2021-03-15 11:30:53 【问题描述】:在我的应用程序中,我获取 Json 条目并将其直接保存在 CoreData 中。 我在实体中添加了额外的 Boolean IsFavorite(默认为 False),让用户标记为收藏并在单独的视图中显示。
到目前为止一切都很好,问题是当我再次从更新的 json 获取内容以引用内容时,女巫已经最喜欢的帖子被复制了。
这就是我获取和保存数据的方式:
class JSONViewModel: ObservableObject
@Published var listings: [ListingModel] = []
// @Published var tags :[Tags] = []
// saving Json to Core Data...
func saveData(contex: NSManagedObjectContext)
listings.forEach (data) in
let entity = Listing(context: contex)
// entity.id = Int64(data.id)
entity.title = data.title
entity.name = data.name
entity.expires = data.expires
entity.adresa = data.adresa
entity.listingtype = data.listingtype
entity.latitude = Double(truncating: NSNumber(value: data.latitude))
entity.longitude = Double(truncating: NSNumber(value: data.longitude))
entity.isFavorite = false
// saving all pending data at once
do
try contex.save()
print("success")
catch
print(error.localizedDescription)
func fetchData(context: NSManagedObjectContext)
let url = "https://... my json"
var request = URLRequest(url: URL(string: url)!)
request.addValue("swiftui2.0", forHTTPHeaderField: "field")
let session = URLSession(configuration: .default)
session.dataTask(with: request) (data, res, _) in
guard let jsonData = data elsereturn
// check for errors
let response = res as! HTTPURLResponse
// checking by status code
if response.statusCode == 404
print("error Api Errror")
// fetching JSON Data ..
do
let listings = try JSONDecoder().decode([ListingModel].self, from: jsonData)
DispatchQueue.main.async
self.listings = listings
self.saveData(contex: context)
catch
print(error.localizedDescription)
.resume()
我使用此代码将帖子标记为收藏:
Button(action: fetchedData!.isFavorite.toggle();
do
try context.save()
catch
print(error)
) Image(systemName: fetchedData!.isFavorite ? "heart.circle.fill" : "heart.circle")
在 ContentView 上,我会像这样加载最新的帖子:
HStack
// checkin if core data exists
if results.isEmpty
if jsonModel.listings.isEmpty
HStack(alignment: .center)
HStack(spacing: 10)
ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: Color("dinamicPillsGrass")))
.scaleEffect(2, anchor: .center)
// fetching data
.onAppear(perform:
jsonModel.fetchData(context: context)
)
.frame(width: UIScreen.main.bounds.width)
.modifier(cardHeight())
// when array is clear indicator appears
// as result data is fetched again
else
HStack(spacing: 20)
ForEach(jsonModel.listings,id: \.self)listing in
NavigationLink (destination: CardDetailView(listing: listing))
HStack
CardViewOrizontal(listing: listing)
.buttonStyle(PlainButtonStyle())
// display fetched Json Data..
else
// results.prefix(?) unde ? cata articole sa arate
HStack(spacing: 20)
ForEach(results.prefix(10))listing in
NavigationLink (destination: CardDetailView(fetchedData: listing))
HStack
CardViewOrizontal(fetchedData: listing)
.buttonStyle(PlainButtonStyle())
.padding(.trailing, 15)
.padding(.leading, 15)
// update finish
.padding(.top, 10)
我像这样更新数据: 注意:我还会检查 Internet 连接。
Button(action:
// clearing data in core data..
if Reachability.isConnectedToNetwork()
//
do
jsonModel.listings.removeAll()
**// This code is deleteing all the saved posts - also the favorite ones**
// results.forEach (listing) in
// context.delete(listing)
//
**// this code is duplicating only the favorite posts**
results.forEach (listing) in
if listing.isFavorite.self == false
context.delete(listing)
jsonModel.listings.removeAll()
else
jsonModel.fetchData(context: context)
try context.save()
catch
print(error.localizedDescription)
print("Network is connected")
self.isError = false
else
print("Network is not connected")
self.isError = true
, label:
HStack(alignment: .center)
Image(systemName: "icloud.and.arrow.down")
.modifier(textSectionIcon())
Text("Update")
.modifier(textSectionTagline())
.padding(5)
.padding(.trailing, 5)
.background(Color("blueLeading"))
.cornerRadius(20)
.modifier(shadowPills())
).alert(isPresented: $isError)
Alert(title: Text("Network is not connected"),
message: Text("WiFi or Cellular not availible. You can still browse offline content!"),
dismissButton: .default(Text("OK")))
如何在不复制收藏的帖子的情况下更新获取?
【问题讨论】:
很明显,当帖子不是收藏夹时,您将其删除,但如果它是收藏夹,则您不收藏(这很好),而是下载并插入 all发布到核心数据。您对每个收藏夹都执行此操作,因此对于 2 个收藏夹,您实际上将下载帖子两次,最终在您的存储中获得三份收藏夹和复制非收藏夹。您需要重新考虑 fetchData 应该如何工作,也需要重新考虑如何调用它,现在它太粗糙了。也许在插入之前检查帖子是否已经存在。 嗨。您将使用 JSON 中的什么值来确定该列表是否已存在于您的核心数据中?我看到您已将 ID 注释掉。可以重新介绍吗? 您好 rlong405 - 请查看更新。谢谢 【参考方案1】:我用过 受 id 约束 并介绍:
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
`现在数据是唯一的,下一个问题是,当我获取 agian 时,收藏夹现在被抹掉了!
这里有新问题:Update CoreData when fetch again from online Json
【讨论】:
以上是关于核心数据 - 再次获取 JSON 时,收藏的帖子变得重复的主要内容,如果未能解决你的问题,请参考以下文章