Hi,
I have the following page (this is a simplified version) where there is a FetchRequest to get a record from CoreData based on an id. This id is obtained from some json that is stored in UserDefaults (returned by the getLodgeData method).
import SwiftUI
struct TestView: View {
var lodge: Lodge = getLodgeData()
@State var lodgeid: Int = -1
var body: some View {
TestViewPage(lodgeid: lodgeid)
.onAppear(perform: {
self.lodgeid = Int(lodge.LodgeID) ?? 0
})
}
}
struct TestViewPage: View {
var lodgeid: Int
@Environment(\.managedObjectContext) var managedObjectContext
var lodge: Lodge = getLodgeData()
@State var favourite = false
//this gets the list
@FetchRequest var cdlodges: FetchedResults<CDLodge>
init(lodgeid: Int) {
self.lodgeid = lodgeid
self._cdlodges = FetchRequest(
entity: CDLodge.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \CDLodge.lodge, ascending: true),
],
predicate: NSPredicate(format: "lodgeid == \(lodgeid)")
)
if cdlodges.isEmpty == false {
//not empty so set fav to true
favourite = true
}
else {
//not a favourite so set to false
favourite = false
}
}
var body: some View {
NavigationView {
ScrollView {
VStack(alignment: .leading) {
VStack {
switch favourite {
case false:
Button(action: {
///save the lodge in core data
//...
favourite = setFav()
})
{
Image("favicon_off")
}
case true:
Button(action: {
///delete the lodge from Core Data
//...
})
{
Image("favicon_on")
}
}
}
Button(action: {
if cdlodges.isEmpty == false {
//not empty so set fav to true
favourite = true
}
else {
//not a favourite so set to false
favourite = false
}
}) {
Text("testing")
}
}
.padding()
}///end of scrollview
.navigationBarTitle("")
.navigationBarHidden(true)
} //end of navigationview
}
}
I want to set a variable (favourite) based on if the dataset that the FetchRequest returns is empty or not.
I tried putting the check after the request, but it always comes back as empty. This is odd as I know that a row is being returned.
I added a button (marked test) that runs the same check, and that works fine so I can only sumise that the initial check is being done before the resultset is finished being populated.
Is there a way that I can do the check when the query updates? At this point I feel that I'm missing something simple, but I just can't seem to see it.
Any help would be greatly appreciated.
thanks
I tried putting the check after the request
Seems you put the check after initializing FetchRequest
, not after the request.
It is hard to predict when exactly the request is made or when the result is updated.
One possible solution would be like this:
struct TestViewPage: View {
var lodgeid: Int
@Environment(\.managedObjectContext) var managedObjectContext
var lodge: Lodge = getLodgeData()
var favourite: Bool {!cdlodges.isEmpty} //<-
//this gets the list
@FetchRequest var cdlodges: FetchedResults<CDLodge>
init(lodgeid: Int) {
self.lodgeid = lodgeid
self._cdlodges = FetchRequest(
entity: CDLodge.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \CDLodge.lodge, ascending: true),
],
predicate: NSPredicate(format: "lodgeid == \(lodgeid)")
)
}
var body: some View {
NavigationView {
ScrollView {
VStack(alignment: .leading) {
VStack {
switch favourite {
case false:
Button(action: {
///save the lodge in core data
//...
})
{
Image("favicon_off")
}
case true:
Button(action: {
///delete the lodge from Core Data
//...
})
{
Image("favicon_on")
}
}
}
}
.padding()
}///end of scrollview
.navigationBarTitle("")
.navigationBarHidden(true)
} //end of navigationview
}
}
With checking favourite
dynamically, you would get the result you want.
(Though, I omitted favourite = setFav()
, which I cannot guess what you want to do with it...)