问题描述
我正在从Json获取数据,并将所有数据一次保存在CoreData中.我介绍了一个新实体"isFavorite",将核心数据发布标记为收藏.问题是,当我再次从服务器获取数据后,isFavorite数据被重置为默认值false.
我这样保存数据:
import SwiftUI导入CoreData类JSONViewModel:ObservableObject {@已发布的var列表:[ListingModel] = []//将Json保存到核心数据中...func saveData(contex:NSManagedObjectContext){listings.forEach {(数据)在让实体=列表(上下文:contex)entity.id = Int64(data.id)实体.标题=数据.标题实体名称=数据名称entity.latitude = Double(截断:NSNumber(值:data.latitude))entity.longitude = Double(截断:NSNumber(值:data.longitude))entity.isFavorite = false//每次我再次获取所有帖子时,其默认值都为isFavorite = false,
女巫正在对付一个哨所的女巫,已经是isFavorite = true
}做{//一次保存所有待处理的数据尝试contex.save()打印(成功")}抓住{打印(error.localizedDescription)}}func fetchData(上下文:NSManagedObjectContext){让url ="json上的https://..."var request = URLRequest(URL:URL(string:url)!)request.addValue("swiftui2.0",对于HTTPHeaderField:"field")let session = URLSession(配置:.default)session.dataTask(with:request){(data,res,_)在守护让jsonData =数据else {return}//检查错误让response = res为!HTTPURLResponse//通过状态码检查如果response.statusCode == 404 {打印(错误Api错误")}//获取JSON数据..做 {让清单=尝试JSONDecoder().decode([ListingModel] .self,来自:jsonData)DispatchQueue.main.async {self.listings =列表self.saveData(contex:上下文)}}抓住 {打印(error.localizedDescription)}}.恢复()}}
如何检查数据是否存在,仅更改新内容?
我还通过"id"设置了约束.并像这样更新PersistentContainer: 让容器:NSPersistentContainerinit(inMemory:Bool = false){容器= NSPersistentContainer(名称:"WebyCoreData")container.viewContext.automaticallyMergesChangesFromParent = truecontainer.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy如果inMemory {container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath:"/dev/null")}container.loadPersistentStores(completionHandler:{如果让error = error as NSError?{fatalError(未解决的错误\(错误),\(error.userInfo)")}})}
任何帮助深表感谢!
也尝试过:
if entity.isFavorite == true {entity.isFavorite = true}别的 {entity.isFavorite = false}
在saveData函数中,尝试执行以下操作:
let listingFetch:NSFetchRequest< Listing>= Listing.fetchRequest()listingFetch.predicate = NSPredicate(格式:"id ==%@",Int64(data.id))做 {让结果:[列表] =尝试contex.fetch(listingFetch)如果results.count == 0 {让实体=列表(上下文:contex)entity.id = Int64(data.id)实体.标题=数据.标题实体名称=数据名称entity.latitude = Double(截断:NSNumber(值:data.latitude))entity.longitude = Double(截断:NSNumber(值:data.longitude))entity.isFavorite = false尝试?contex.save()打印(插入列表")}别的{设实体=结果[0]实体.标题=数据.标题实体名称=数据名称entity.latitude = Double(截断:NSNumber(值:data.latitude))entity.longitude = Double(截断:NSNumber(值:data.longitude))entity.isFavorite = true尝试?contex.save()打印(更新列表")}}将let错误捕获为NSError {print(插入/更新列表\(error),\(error.userInfo)时出错")}
使用Marius的完整属性列表进行更新.还修改了错字
func saveData(contex:NSManagedObjectContext){listings.forEach(){(数据)在let listingFetch:NSFetchRequest< Listing>= Listing.fetchRequest()listingFetch.predicate = NSPredicate(格式:"id =%@",data.id)做 {让结果:[列表] =尝试contex.fetch(listingFetch)如果results.count == 0 {让实体=列表(上下文:contex)entity.id = Int64(data.id)实体.标题=数据.标题实体名称=数据名称entity.category = data.category实体.图像=数据.图像实体.发布日期=数据发布日期entity.tagline = data.tagline实体.内容=数据.内容entity.coverimage = data.coverimageentity.galleryunu = data.galleryunuentity.gallerydoi = data.gallerydoientity.gallerytrei =数据.gallerytreientity.saleprice = Int64(截断:NSNumber(值:data.saleprice))entity.rentprice = Int64(截断:NSNumber(值:data.rentprice))实体.电话=数据.电话实体.电子邮件=数据.电子邮件实体.区域= Int64(截断:NSNumber(值:数据.区域))entity.rooms = Int64(截断:NSNumber(值:data.rooms))实体.床= Int64(截断:NSNumber(值:数据.床))实体.浴室= Int64(截断:NSNumber(值:数据浴室))entity.expires = data.expiresentity.adresa = data.adresa实体.列表类型=数据.列表类型entity.latitude = Double(截断:NSNumber(值:data.latitude))entity.longitude = Double(截断:NSNumber(值:data.longitude))entity.isFavorite = false尝试?contex.save()打印(插入列表")}别的{设实体=结果[0]entity.id = Int64(data.id)实体标题=数据标题实体名称=数据名称entity.category = data.category实体.图像=数据.图像实体.发布日期=数据发布日期entity.tagline = data.tagline实体.内容=数据.内容entity.coverimage = data.coverimageentity.galleryunu = data.galleryunuentity.gallerydoi = data.gallerydoientity.gallerytrei =数据.gallerytreientity.saleprice = Int64(截断:NSNumber(值:data.saleprice))entity.rentprice = Int64(截断:NSNumber(值:data.rentprice))实体.电话=数据.电话实体.电子邮件=数据.电子邮件实体.区域= Int64(截断:NSNumber(值:数据.区域))entity.rooms = Int64(截断:NSNumber(值:data.rooms))实体.床= Int64(截断:NSNumber(值:数据.床))实体.浴室= Int64(截断:NSNumber(值:数据浴室))entity.expires = data.expiresentity.adresa = data.adresa实体.列表类型=数据.列表类型entity.latitude = Double(截断:NSNumber(值:data.latitude))entity.longitude = Double(截断:NSNumber(值:data.longitude))entity.isFavorite = true尝试?contex.save()打印(更新列表")}}将let错误捕获为NSError {print(插入/更新列表\(error),\(error.userInfo)时出错")}}}
I am fetching data from Json and save all at once in CoreData. I introduced a new entity "isFavorite" to mark core data posts as favorites. The problem is that after i fetch again from server the isFavorite data is resseting to the default false.
I save the data like this:
import SwiftUI
import CoreData
class JSONViewModel: ObservableObject {
@Published var listings: [ListingModel] = []
// 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.latitude = Double(truncating: NSNumber(value: data.latitude))
entity.longitude = Double(truncating: NSNumber(value: data.longitude))
entity.isFavorite = false // everytime i fetch again all the post get default value as isFavorite = false,
witch is overighting tha acual post's witch have already isFavorite = true
}
do{
// saving all pending data at once
try contex.save()
print("success")
}
catch{
print(error.localizedDescription)
}
}
func fetchData(context: NSManagedObjectContext){
let url = "https://... on line 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 else{return}
// 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()
}
}
How can i check if data exist and only change what is new?
i have also set Constraints by "id".and updated the PersistentContainer like this::
let container: NSPersistentContainer
init(inMemory: Bool = false) {
container = NSPersistentContainer(name: "WebyCoreData")
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") }
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
}
Any help is deeply appreciated!
Have tried also:
if entity.isFavorite == true {
entity.isFavorite = true}
else {
entity.isFavorite = false}
In your saveData function, try something like this:
let listingFetch: NSFetchRequest<Listing> = Listing.fetchRequest()
listingFetch.predicate = NSPredicate(format: "id == %@", Int64(data.id))
do {
let results:[Listing] = try contex.fetch(listingFetch)
if results.count == 0 {
let entity = Listing(context: contex)
entity.id = Int64(data.id)
entity.title = data.title
entity.name = data.name
entity.latitude = Double(truncating: NSNumber(value: data.latitude))
entity.longitude = Double(truncating: NSNumber(value: data.longitude))
entity.isFavorite = false
try? contex.save()
print ("Inserted Listing")
}
else
{
let entity = results[0]
entity.title = data.title
entity.name = data.name
entity.latitude = Double(truncating: NSNumber(value: data.latitude))
entity.longitude = Double(truncating: NSNumber(value: data.longitude))
entity.isFavorite = true
try? contex.save()
print ("Updated Listing")
}
} catch let error as NSError {
print("error inserting / updating Listing \(error), \(error.userInfo)")
}
Update with Marius's full list of properties.Also modified typo
func saveData(contex: NSManagedObjectContext) {
listings.forEach() { (data) in
let listingFetch: NSFetchRequest<Listing> = Listing.fetchRequest()
listingFetch.predicate = NSPredicate(format: "id = %@", data.id)
do {
let results:[Listing] = try contex.fetch(listingFetch)
if results.count == 0 {
let entity = Listing(context: contex)
entity.id = Int64(data.id)
entity.title = data.title
entity.name = data.name
entity.category = data.category
entity.image = data.image
entity.publishdate = data.publishdate
entity.tagline = data.tagline
entity.content = data.content
entity.coverimage = data.coverimage
entity.galleryunu = data.galleryunu
entity.gallerydoi = data.gallerydoi
entity.gallerytrei = data.gallerytrei
entity.saleprice = Int64(truncating: NSNumber(value: data.saleprice))
entity.rentprice = Int64(truncating: NSNumber(value: data.rentprice))
entity.phone = data.phone
entity.email = data.email
entity.area = Int64(truncating: NSNumber(value: data.area))
entity.rooms = Int64(truncating: NSNumber(value: data.rooms))
entity.beds = Int64(truncating: NSNumber(value: data.beds))
entity.bathrooms = Int64(truncating: NSNumber(value: data.bathrooms))
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
try? contex.save()
print ("Inserted Listing")
}
else
{
let entity = results[0]
entity.id = Int64(data.id)
entity.title = data.title
entity.name = data.name
entity.category = data.category
entity.image = data.image
entity.publishdate = data.publishdate
entity.tagline = data.tagline
entity.content = data.content
entity.coverimage = data.coverimage
entity.galleryunu = data.galleryunu
entity.gallerydoi = data.gallerydoi
entity.gallerytrei = data.gallerytrei
entity.saleprice = Int64(truncating: NSNumber(value: data.saleprice))
entity.rentprice = Int64(truncating: NSNumber(value: data.rentprice))
entity.phone = data.phone
entity.email = data.email
entity.area = Int64(truncating: NSNumber(value: data.area))
entity.rooms = Int64(truncating: NSNumber(value: data.rooms))
entity.beds = Int64(truncating: NSNumber(value: data.beds))
entity.bathrooms = Int64(truncating: NSNumber(value: data.bathrooms))
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 = true
try? contex.save()
print ("Updated Listing")
}
} catch let error as NSError {
print("error inserting / updating Listing \(error), \(error.userInfo)")
}
}
}
这篇关于从联机Json再次获取时更新CoreData的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!