Andrew James
Andrew James

Reputation: 46

How can I retrieve the last created Core Data parent entity along with its 1 to Many related entities in a @FetchRequest?

In Core Data have 2 Entities - LocationSet and Location in a 1 to Many relationship I want to Fetch all the Location children related to the last created LocationSet (using its property of .created date) to use in a View

My 2 FetchRequests work fine on their own but I would like to use the LocationSet returned in my first Fetch as a predicate for the 2nd fetch of the Location children

These are my FetchRequests for each entity,

@FetchRequest(entity: LocationSet.entity()
 ,sortDescriptors: [NSSortDescriptor(keyPath: \LocationSet.created, ascending: true)]
 )var fetchedLocSets: FetchedResults<LocationSet>

@FetchRequest(entity: Location.entity()
 ,sortDescriptors: [NSSortDescriptor(keyPath: \Location.name, ascending: true)]
 )var fetchedLocations: FetchedResults<Location>

I have tried doing this in an init() but its not working and seems overly complicated so thinking this must have a more elegant solution?

I tried using init() to do the LocationSet fetch first to then use in the Location fetch but didn't work and also get the purple error Accessing StateObject's object without being installed on a View. This will create a new instance each time.

init(){
  let requestSets: NSFetchRequest<LocationSet> = LocationSet.fetchRequest()
  requestSets.sortDescriptors = [NSSortDescriptor(keyPath: \LocationSet.name, ascending: true)]
  let fetchLS = FetchRequest<LocationSet>(fetchRequest: requestSets)
       
  if let locset = fetchLS.wrappedValue.first {
    let request: NSFetchRequest<Location> = Location.fetchRequest()
    request.sortDescriptors = [NSSortDescriptor(keyPath: \Location.name, ascending: true)]
    request.predicate = NSPredicate(format: "set_ofLocations == %@", locset)
    _fetchedLocations = FetchRequest<Location>(fetchRequest: request)
  }
}

Upvotes: 1

Views: 49

Answers (2)

Andrew James
Andrew James

Reputation: 46

I solved this by another approach - essentially flipped the query. I used a predicate to retrieve all Locations limited by a give LocationSet id.

let uuidPred = NSPredicate(format:  "locationset.uuid_ == %@", UUID(uuidString: lastUUID.rawValue)! as CVarArg)

Upvotes: 0

DudeOnRock
DudeOnRock

Reputation: 3831

I have pretty much given up on @FetchRequest inside of my Views because it is so limited in functionality compared to CoreData at large.

What I normally do is:

  • Create a manager-object for accessing my CoreData model (My data managers are @globalActors to more easily facilitate background fetches but this is not necessary and might complicate things for you if you are not 100% comfortable with merging contexts from different threads.)
  • in onAppear I fetch my data inside a Task using my manager and once retrieved I update a @State property on the view with the fetched data (using MainActor.run to avoid more purple errors when fetching from a background context)

Upvotes: 1

Related Questions