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)")
}
}
}