2

I have planned to create a mini project using iOS 17 Beta in Xcode 15 Beta.

So, I created a new project using SwiftData and SwiftUI.

import SwiftUI
import SwiftData

struct HomeScreen: View {
    
    @Environment(\.modelContext) private var modelContext
    @Query private var dayLogs: [DayLog]
            
    var todayLog: DayLog {
        #Predicate({}) var DayLog // how to predicate currentDay record from dayLogs.
    }
   ...

Day Log SwiftModel is:

@Model
final class DayLog: Identifiable {
    let id = UUID()
    
    var createdDate: Date
    
    var note: String = ""
}

I don't know how to filter this array using Swift Macros #Predicate

HangarRash
  • 7,314
  • 5
  • 5
  • 32
Kathiresan Murugan
  • 2,783
  • 3
  • 23
  • 44
  • You don’t need #Predicate for a computed property like that when you have already fetched all objects in `dayLogs`, use a `filter` instead – Joakim Danielson Jun 10 '23 at 08:47

2 Answers2

1

Since you are using @Query for dayLogs, the values have already been fetched.

If you want to fetch values with some predicate it would be better to use

@Query(filter: Predicate, sort: KeyPath, order: SortOrder, animation: Animation)

Or:

@Query(<descriptor: FetchDescriptor>, animation: Animation)

If you want to filter after fetching data, use simple .filter()

Tyler2P
  • 2,324
  • 26
  • 22
  • 31
Abhilash
  • 54
  • 3
1

I tried this logic. It’s working fine for me.

extension Collection where Element == DayLog {

    /// Today Log filter.
    func todayLog() -> [DayLog] {
        let currentDate = Date()

        let from = currentDate.startOfDay
        let to = currentDate.endOfDay

        let todayPredicate = #Predicate<DayLog> { from < $0.startDate && $0.startDate < to }

        do {
            let result = try filter(todayPredicate)
            return result

        } catch let error {
            print("Failed to filter today record from DayLog. Error: \(error.localizedDescription)")
        }
        return []
    }
}

And this for the Date function:

extension Date {

    var startOfDay: Date {
        return Calendar.current.startOfDay(for: self)
    }

    var endOfDay: Date {
        var components = DateComponents()
        components.day = 1
        components.second = -1
        return Calendar.current.date(byAdding: components, to: startOfDay)!
    }
}

Call it by:

 let todayLog = self.dayLogs.todayLog().last
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kathiresan Murugan
  • 2,783
  • 3
  • 23
  • 44