I’m trying to extend my „Find XYZ“ action of my Reading-AppEntity to accept filtering for another Meter-AppEntity type. So basically I want to get all elements that have a Core Data relationship to the same object. Though, for some reason the filtering doesn’t work as expected and and ignores which AppEntity I select to filter for.
The Setup
In my database I have a Meter which has a relationship to Readings. I’ve bridged my Core Data entities to the AppEntity protocol, to use it in Shortcuts the following way:
struct ReadingEntity: AppEntity, Identifiable {
var id: UUID
@Property(title: "Value")
var value: Double
@Property(title: "Meter")
var readingMeter: MeterEntity
// Visual representation and other required stuff …
// Create IntentEntity from Core Data Object
init(from reading: Reading) {
self.id = reading.wrappedID
self.value = reading.value
// Link to Meter
if let meter = reading.meterRelationship {
self.readingMeter = MeterEntity(from: meter)
}
}
}
struct MeterEntity: AppEntity, Identifiable {
var id: UUID
@Property(title: "Title")
var title: String
// …
// Visual representation and other required stuff …
// Create IntentEntity from Core Data Object
init(from meter: Meter) {
self.id = meter.wrappedID
self.title = meter.wrappedTitle
}
}
To support the Find Reading action I’ve implemented the filter options (besides the other required things):
struct ReadingIntentQuery: EntityPropertyQuery {
// Other required functions
// Filter Options
static var properties = EntityQueryProperties {
Property(\ ReadingEntity.$readingMeter) {
EqualToComparator { NSPredicate(format: "readingMeter.id = %@", $0.id as CVarArg) }
}
}
// Handling of Filtering
func entities(
matching comparators: [NSPredicate],
mode: ComparatorMode,
sortedBy: [EntityQuerySort< ReadingEntity >],
limit: Int?
) async throws -> [ReadingEntity] {
// Custom Predicate
let predicate = NSCompoundPredicate(type: mode == .and ? .and : .or, subpredicates: comparators)
// Custom sorting handling …
return try IntentsDataHandler.shared.getReadings(matching: predicate, sortedBy: sortDescriptors, limit: limit)
}
}
The Problem
The issue I’m having is, that no matter which Meter I select in the Find Reading dropdown-list, the EqualToComparator always returns the ID of the first Meter object in the dropdown-list. For some reason it even returns this first meter-ID, even when nothing is selected yet. Not sure why the selection in the filter action is ignored here …
Looks like a logic issue. Though, I don’t know what I’m doing wrong here. Maybe someone can help?