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.
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 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?
As mentioned in the comments, this was an issue introduced with iOS 17 and got fixed with iOS 17.2.
The code above works fine now.