I'm facing an issue in my iOS app's architecture involving CoreData, the HistoryCallDataService class, and the HistoryViewModel. I'm hoping someone can help shed light on the problem I'm encountering.
Problem Description:
I'm working with CoreData and have an array that I'm managing through the HistoryCallDataService class.
class HistoryCallDataService {
private let container: NSPersistentContainer
private let containerName = "CallHistoryData"
private let entityName = "HistoryData"
@Published var savedEntities: [HistoryData] = []
I'm observing changes in the savedEntities property of the HistoryCallDataService class using the historyDataService.$savedEntities publisher. When the app starts, the array is updated correctly. However, if I add new content, the savedEntities array updates, but the historyArray in the HistoryViewModel does not reflect these changes.
import Foundation
import Combine
class HistoryViewModel: ObservableObject {
@Published var searchText:String = ""
@Published var historyArray: [HistoryData] = []
private let historyDataService = HistoryCallDataService()
private var cancellables = Set<AnyCancellable>()
var selectedContact: HistoryData? = nil
@Published var filteredContacts: [HistoryData] = []
init(){
addSubscribers()
}
func addSubscribers(){
historyDataService.$savedEntities
.debounce(for: 1.0, scheduler: RunLoop.main)
.sink { [weak self] (returnData) in
guard let self = self else { return }
self.historyArray = returnData
self.updateFilteredContacts()
}
.store(in: &cancellables)
}
func updateFilteredContacts() {
if searchText.isEmpty {
filteredContacts = historyArray
} else {
filteredContacts = historyArray.filter { contact in
contact.firstName?.localizedCaseInsensitiveContains(searchText) ?? false ||
contact.lastName?.localizedCaseInsensitiveContains(searchText) ?? false ||
contact.telephone?.localizedCaseInsensitiveContains(searchText) ?? false
}
}
}
The view:
private var contactList: some View{
List{
ForEach(vm.filteredContacts) { item in
HStack{
VStack(alignment: .leading){
Text("\(item.firstName ?? "N/A") \(item.lastName ?? "N/A" )")
.fontWeight(.semibold)
Text("\(item.telephone ?? "N/A")")
.fontWeight(.medium)
.padding(.top,1)
}
Spacer()
VStack(alignment: .trailing){
Text("\(item.time ?? "N/A")")
.fontWeight(.medium)
Text("\(item.callHidden ? "Hidden" : "Normally ")")
.foregroundColor(item.callHidden ? Color.theme.red : Color.theme.black)
.fontWeight(.bold)
.padding(.top,1)
}
}
.onTapGesture {
vm.selectedContact = item
showingCallAlert.toggle()
}
.listRowBackground(vm.selectedContact?.telephone == item.telephone && showingCallAlert ? Color.theme.gray : nil)
}
.onDelete(perform: { indexSet in
for index in indexSet {
let contactToDelete = vm.filteredContacts[index]
vm.delete(entity: contactToDelete)
}
})
}
.onChange(of:
vm.searchText) { _ in
vm.updateFilteredContacts()
}
.onChange(of: scenePhase) { newPhase in
if newPhase == .active {
print("Active")
vm.updateFilteredContacts()
}
}
.lineLimit(1)
.listStyle(.plain)
}
If anyone has encountered a similar situation or has insights into what might be causing this behavior, I would greatly appreciate your guidance. Thank you in advance for your help!