Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support testing against "now" in predicates #499

Open
JetForMe opened this issue Mar 21, 2024 · 4 comments
Open

Support testing against "now" in predicates #499

JetForMe opened this issue Mar 21, 2024 · 4 comments

Comments

@JetForMe
Copy link

Today I ran into an issue while converting CoreData code to SwiftData: I couldn't create a #Predicate that compared against “now”:

#Predicate<PlugReminder>
{ inReminder in
    inReminder.fireDate >= Date()
}

This seems to me to be a fairly common use case. Is there a way for #Predicate to understand an expression like this?

@jmschonfeld
Copy link
Contributor

This depends a bit on your definition of "now". If "now" refers to the Date at which the predicate is constructed/initialized, you can express it like the following:

let currentDate = Date()
let predicate = #Predicate<PlugReminder> { inReminder in
    inReminder.fireDate >= currentDate
}

But that will capture the current date/time when the predicate is constructed - if the predicate is evaluated at a later date then currentDate will not "update". We don't currently have a mechanism to calculate the current date at the time of predicate evaluation for two reasons:

  1. There's no way to represent "the current date" at a syntactic level inside of a Predicate. We don't support arbitrary function calls so the Date() initializer isn't available (and I don't feel we'd want to support this either since we don't support initializers in the general case), and we can't support static properties like Date.now because Swift does not support keypaths to static properties (this is a language limitation that would need to be implemented/lifted) which is outlined a bit in Comparison predicate cannot refer to ComparisonResult enum #318.
  2. I'm not certain if we have a great way to represent the "current" date/time in the converted representations of Predicate, for example in cases where SwiftData or CoreData converts this Predicate to a SQL query while it may be possible, I'm not certain if we have a great way to represent this in the SQL query.

@JetForMe
Copy link
Author

Yeah, fortunately in my case I was able to solve it as you suggest, at the expense of some brevity in SwiftUI’s @Query macro. Unfortunately, to continually update the result set with a new "now" will probably require restructuring the views to pass in the desired date…actually i don't even think that would work with @Query.

In any case, my thought was to be able to specify "now" in a way that gets embedded into the evaluation of the predicate, rather than the creation of it. Most flavors of SQL support this, but iiuc Predicates can be used anywhere, so they probably need their own encoding of "now."

@hassila
Copy link
Contributor

hassila commented Mar 21, 2024

Just had to mentioned this with regard to static keypaths then:

https://forums.swift.org/t/pitch-metatype-keypaths/70767

@jmschonfeld
Copy link
Contributor

Yeah we can keep this issue to track investigating supporting the concept of "now" within the evaluation of the predicate. I think we'll likely want to represent this as Date.now so we'll likely need static keypaths (thanks @hassila for the reference to the pitch!), but if we were to in some language version get support for that we can think through how Date.now might be represented in external formats such as NSPredicate, SQL (for SwiftData/CoreData), etc. Predicate doesn't need to support every format (since developers can write their own Predicate types using our APIs to selectively include/exclude operators based on support for another format), but we'll have to consider the main NSPredicate/SQL uses in particular for Predicate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants