I have a tax Create/Edit View, and List View,View Model Class as Observable Object.
I update values to core data in viewModel class from an edit view, that updated values are not reflecting in list view which uses the same view Model class. The list view only updated when I go back to other screen and come to this list screen screen or if restart the app
Please kindly suggest
List View Code
struct TaxListView: View {
@State var searchTerm:String = ""
@State var isTaxSelected = false
@State var seletedTax:TaxCodesList = TaxCodesList(businessId: "", taxID: "", taxName: "", taxRate: 0.0, taxtype: "", taxCodes: [TaxCodeList]())
@ObservedObject var taxViewModel = TaxViewModel()
@Environment(\.presentationMode) var mode
var body : some View {
VStack{
List{
ForEach(taxViewModel.arrTaxCodes, id: \.taxID){ tax in
TaxlistRow(tax: tax, selectedTax: $seletedTax, taxSelected: $isTaxSelected)
}
}
}
}
View Model Class
class TaxViewModel:ObservableObject {
@Published var arrTaxCodes:[TaxCodesList] = []
@Published var arrTempTaxCodes:[TaxCodesList] = []
let context = PersistenceController.shared.container.viewContext
func getTaxCodes(){
let fetchRequest : NSFetchRequest<TaxCodes> = TaxCodes.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "businessId = %@", Constants.businessID ?? "")
do {
let result = try context.fetch(fetchRequest)
arrTaxCodes.removeAll()
for data in result {
arrTaxCodes.append(TaxCodesList(responseObj: data))
}
arrTempTaxCodes = arrTaxCodes
} catch {
print(error.localizedDescription)
}
}
//MARK: Update Tax
func updateTax(tax:TaxCodesList, completion:@escaping (Bool,String) -> Void) {
let fetchRequest : NSFetchRequest<TaxCodes> = TaxCodes.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "taxID = %@", tax.taxID)
do {
let result = try context.fetch(fetchRequest)
guard let objectToUpdate = result.first else {
return
}
var taxCodesObj = [[String:Any]()]
///// assigning values to taxCodesObj
objectToUpdate.setValue(tax.taxName ,forKey: "taxName")
objectToUpdate.setValue(tax.taxRate, forKey: "taxRate")
objectToUpdate.setValue(tax.taxType, forKey: "taxType")
objectToUpdate.setValue(["taxCodes":taxCodesObj], forKey: "taxCodes")
do {
try context.save()
//Context.refreshAllObjects()
completion(true,"Tax Updated Successfully")
} catch {
completion(true,error.localizedDescription)
print(error.localizedDescription)
}
} catch {
completion(true,"TaxId not Found")
print(error.localizedDescription)
}
}
}
Edit View
struct CreateTaxView: View {
///// Some Variables
@ObservedObject var taxViewModel:TaxViewModel
@Environment(\.presentationMode) var mode
func saveTax(){
//// Codes to create tax Object
taxViewModel.updateTax(tax: tax) { flag, msg in
print(msg)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
self.mode.wrappedValue.dismiss()
})
}
}
var body: some View {
Form {
Section {
///// Some Views
}
.onAppear{
taxViewModel.getTaxCodes(Context: viewContext)
if isFromUpdate && isInitialLoad {
/////Assign values to variables
}
}
}
.navigationBarTitle(Text(navTitle))
.navigationBarItems(trailing: Button{
saveTax()
} label:{
Text("Save")
} )
}
func delete(at offsets:IndexSet){
taxCodes.remove(atOffsets: offsets)
}
TaxCodesList Struct
struct TaxCodesList{
var businessId:String
var taxID:String
var taxName:String
var taxRate: Double
var taxType:String
var taxCodes:[TaxCodeList]
////Init code
//Initialize from core data object
init(responseObj:TaxCodes){
self.businessId = responseObj.businessId ?? ""
self.taxID = responseObj.taxID ?? ""
self.taxName = responseObj.taxName ?? ""
self.taxRate = responseObj.taxRate
self.taxType = responseObj.taxType ?? ""
let payload = responseObj.taxCodes?["taxCodes"] as? [[String:Any]] ?? [[String:Any]()]
var tempArr = [TaxCodeList]()
tempArr.removeAll()
for data in payload {
if !(data["taxId"] as? String ?? "").isEmpty {
tempArr.append(TaxCodeList(responseObj: data))
}
}
self.taxCodes = tempArr
}
}