Can ObservedResults have a computed filter applied?

I’m working in SwiftUI and my objective is to display a view that observes results for the past week - functionally equivalent to:

let today = Calendar.current.startOfDay(for: Date())
let oneWeekAgo = calendar.date(byAdding: .day, value: -7, to: today)!
let logs = try! Realm().objects(Log.self).filter("entryDate BETWEEN {%@, %@}", today, oneWeekAgo)

My current understanding is that I can’t pass in a computed predicate like this into the ObservedResults wrapper initializer. (If I’m mistaken please let me know.) Is calling the above code on view initialization and observing it manually via notification tokens the appropriate/optimal method of achieving the desired result?

Any advice greatly appreciated - thanks!

Hi @Rudi_Strahl,
You can pass an NSPredicate to @ObservedResults as a filter…

@ObservedResults(Decisions.self, filter: NSPredicate(format: "isSoft == NO AND isSplit == NO")) var decisions

I’ve not had the chance to check whether that predicate can be dynamic.

There’s been some recent work to have “type-safe” queries (i.e. not using strings to formulate the query). realm-cooa 10.19 contains the latest enhancements.

1 Like

Thanks @Andrew_Morgan - after some experimentation, this doesn’t appear possible at the moment given how initialization of view variables and wrappers work in SwiftUI. I was able to achieve the results by using an ObservableObject and initializing a @Published var logs: Result<Log>.

Thanks for thinking about this with me!

Hi @Rudi_Strahl,

you’re correct that the query for @ObservedResults can’t include a variable because of SwiftUI rules.

Recent versions of realm-cocoa now include “type-safe” queries (using where instead of filter). So, for example you can now filter results like this…

struct DecisionView: View {
    @ObservedResults(Decisions.self) var unfilteredDecisions
    
    let isSoft: Bool = true
    
    var body: some View {
        var decisions = unfilteredDecisions.where {
            $0.isSoft == isSoft
        }
        return VStack {
....
}

There’s a PR in review that lets you apply a filter directly in the initial query:

@ObservedResults(Decisions.self, where: { $0.isSoft == true }) var decisions

But the SwiftUI view rules still apply, and you can’t use variables or constants in the query. i.e. This statement fails to build:

@ObservedResults(Decisions.self, where: { $0.isSoft == isSoft }) var decisions
3 Likes

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.