In my app i fetch Json entries and save it directly in CoreData. I added aditional Boolean IsFavorite (default False) to the entyti to let user mark as favorite and display it in a separate view.
So far so good, the problem is that when i fetch again to refres the content from updated json the Posts witch are alreadi favorite get doplicated.
This is how i fetch and save the data:
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 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()
}
}
I mark posts as favorite with this code:
Button(action: { fetchedData!.isFavorite.toggle();
do {
try context.save()
}
catch {
print(error)
} }) { Image(systemName: fetchedData!.isFavorite ? "heart.circle.fill" : "heart.circle")
On the ContentView i load latest post like this:
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)
And i update the data like this: Note: i also check for Internet connection.
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")))
}
How can i update the fetching withowt duplicating the favorited posts?
i have used Constrains by id and introduced:
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
`Now the data is unique, next issue is that the favorites are now getting wipped when i fetch agian!
New question here: Update CoreData when fetch again from online Json