I have a model view that has fetching contacts function:
class ContactsStore: ObservableObject {
@Published var contacts = [CNContact]()
func fetch() {} ...
And then in my View:
@EnvironmentObject var store: ContactsStore
var groupedContacts: [String: [CNContact]] {
.init (
grouping: store.contacts,
by: {$0.nameFirstLetter}
)
}
...
List() {
ForEach(self.groupedContacts.keys.sorted(), id: \.self) { key in ...
I've shortened my code for the convenience, will add/edit if needed. The issue I faced - every time my View is rendered the fetch
function is called and my array of contacts is duplicated in my view. TIA for a help
UPD: Duplication happens due to method calling fetch
in the List .onAppear
. So I'm looking at how to call this method only once and not every time the View appears.
You can do fetch in Init() like that:
struct someView: View{
var list: [Settings]
init(){
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let fetchRequest: NSFetchRequest<Settings> = Settings.fetchRequest()
//... some order and filter if you need
self.list = context.fetch(fetchRequest)
}
var body: some View{
...
ForEach(list){settings in
...
}
...
}
}
Didn't try it with grouping, but you asked how to fetch only once. The answer is - in init().
But you cant get the @Environment
in init
, so i get the context
from AppDelegate
. Or you can pass the context
as init
parameter