SwiftData: Solving Filtering by an Entity in the Predicate
Tags: swiftdata, swift, swiftui, filtering
Published: 2024-04-26 04:33:54

I just wanted to start out by saying that this is an abridged version of my [original published version from December 15, 2023 that you can find on my website here](https://www.simplykyra.com/swiftdata-problems-with-filtering-by-entity-in-the-predicate/).

---

When moving my apps over from `CoreData` to `SwiftData` I came across a problem where I wasn't able to filter my query by another entity within its predicate. Whenever I did and tried to build the project it kept compiling and compiling and would eventually fail so the time wasted waiting while trying to solve the issue was another aggravation on top of it all. 

To demonstrate the problem I took the [iTour](https://github.com/twostraws/iTour?ref=simplykyra.com) example project from [Hacking with Swift](https://www.hackingwithswift.com) and altered it a bit to showcase my problem and, eventually, the solution. 

In his app there are two main data models. You have destinations you can visit and each one has a list of sights you can see at that destination. So for example if you were to visit Alberta (the destination) you could visit many sights while there like: [Banff, Lake Louise](https://www.banfflakelouise.com), [Royal Tyrrell Museum](https://tyrrellmuseum.com),  and [West Edmonton Mall](https://www.wem.ca). While a `Destination` can include multiple `Sight`s each `Sight` can only belong to one `Destination`. His example didn't show my issue but I altered it to include a list of `Sight`s that needed to be filtered by the `id` of a `Destination` thus recreating my problem. 

![Image showing one of the errors](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xqlivdsd267qpk9o8e7h.png)

The problem, once solved, was very simple. I was filtering the `Sight` data thus I could only filter by the data model `Sight` and no other ones. My problem came when I introduced the `Destination`. To get around this I took the `persistentModelID` from the `Destination` before entering into the `Predicate` to filter by. That worked!

![Image shows the filtered data in two ways.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8f9msqrbbvr505avl81z.png)

The working code, in case you want to use it towards your solution, is: 

```
init(sort: [SortDescriptor<Sight>], searchString: String, destination: Destination?) {
  // Make a point of grabbing 
  if let thisID = destination?.persistentModelID {
    _sights = Query(filter: #Predicate<Sight> {
      if searchString.isEmpty {
        return $0.destination?.persistentModelID == thisID
      } else {
        return $0.destination?.persistentModelID == thisID && $0.name.localizedStandardContains(searchString)
      }
    }, sort: sort)
  } else {
    // if id is nil than I don't want ANYTHING that said you could instead return $0.name.localizedStandardContains(searchString)
    _sights = Query(filter: #Predicate<Sight> { currSight in
      return false
    }, sort: sort)
  }
}
```

And with that the issue was solved! If you want more information about the problem, the example, the building issues, or the solution itself you can check out my SimplyKyra website where I [published the longer and original version of this post back in December of 2023](https://www.simplykyra.com/swiftdata-problems-with-filtering-by-entity-in-the-predicate/).

Hope you have a great day!