2

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?

5
  • I am seeing this same issue, but only on iOS 17. On iOS 16, the filter parameter is saved in the shortcut and passed to my code, as expected. On iOS 17, the parameter's default is always passed to my code and if I close the shortcut and reopen it, I can see my selection wasn't even saved. Is there some API change or is this an iOS 17 bug? Commented Oct 23, 2023 at 18:16
  • Quick amendment, to be more specific: On iOS 17, the first value returned from EntityQuery suggestedEntities() is always passed as the filter parameter. My actual selection is ignored and also isn't saved. Commented Oct 23, 2023 at 18:43
  • Thanks for pointing out that this is an issue starting with iOS 17! I didn’t check that before. Running the same code in the iOS 16.4 simulator now, works just fine. Have you tested it on iOS 17.1? Commented Oct 23, 2023 at 19:37
  • Does not work in 17.1 RC. Commented Oct 25, 2023 at 15:28
  • This issue seems to be fixed with iOS 17.2 Beta 2 now! At least in my testing it works as expected. Commented Nov 11, 2023 at 16:21

1 Answer 1

0

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.