Summary of the Issue
I am attempting to use Swift’s predicate macro to filter/search through a data collection in SwiftData. However, I’m encountering errors related to the construction and type of the predicate that I can’t debug.
I expect the #Predicate
used in this method:
public func fetchChildGiven(grandParent: GrandParent) throws -> Child {
guard let parent = grandParent.parent else {
throw DataStoreError.entityNotFound(
msg: "\(grandParent) did not reproduce/adopt"
)
}
let predicate = #Predicate<Child> {
$0.parent == parent
}
let fetchDescriptor = FetchDescriptor<Child>(predicate: predicate)
do {
let fetchedResults = try context.fetch(fetchDescriptor)
guard let fetched = fetchedResults.first else {
throw DataStoreError.entityNotFound(
msg: "no child found for parent: \(parent)"
)
}
return fetched
} catch {
let msg = error.localizedDescription
print("\(msg)")
throw DataStoreError.entityNotFound(
msg: "error fetching child for parent: \(parent) - \(msg)"
)
}
}
to find the entity in question or throw an error given the setup below:
@Model class GrandParent {
@Relationship(deleteRule: .cascade) public var parent: Parent?
init(parent: Parent? = nil) {
self.parent = parent
}
}
@Model class Parent {
@Relationship(inverse: \GrandParent.parent) var grandParent: GrandParent
@Relationship(deleteRule: .cascade) public var child: Child?
init(grandParent: GrandParent, child: Child? = nil) {
self.grandParent = grandParent
self.child = child
}
}
@Model class Child {
@Relationship(inverse: \Parent.child) public var parent: Parent
init(parent: Parent) {
self.parent = parent
}
}
Instead, it raises the error message:
Cannot convert value of type 'PredicateExpressions.Equal<PredicateExpressions.KeyPath<PredicateExpressions.Variable<Child>, Parent>, PredicateExpressions.Value<Parent>>' to closure result type 'any StandardPredicateExpression<Bool>'
which when expanded reveals this:
Foundation.Predicate<Budget>({
PredicateExpressions.build_Equal(
lhs: PredicateExpressions.build_KeyPath(
root: PredicateExpressions.build_Arg($0),
keyPath: \.parent
),
rhs: PredicateExpressions.build_Arg(parent)
)
})
Summary of the Problem
The error message suggests that there is a type mismatch in the construction
of the predicate expression. Specifically, the equality comparison between
the parent property of Child and the provided parent value is not being
recognized as a valid StandardPredicateExpression.
Request for Help
I would appreciate any help understanding how to correctly construct the
predicate using Swift’s predicate macro in this context so that it can
filter the Child entities based on the parent property