使用谓词过滤核心数据以仅显示今天的条目(过滤器停止工作)

问题描述 投票:0回答:0

坚持解决这个问题,请提供帮助。 预期行为:

  • 用户每天至少输入一个条目。
  • 用户看到“请输入”按钮
  • 除非他们已经有,否则按钮会显示“已保存”,如果他们点击它,它将转到 HistoryView。 (按钮切换到导航在视觉上表明发生了什么事)。

我的想法是在日期上应用谓词以按一天的开始进行过滤,并使用 if 语句来交换他们看到的内容。

当我应用下面的代码时,它在模拟器和应用程序中运行良好,但几天后谓词停止工作。我在一天开始时打开应用程序,它显示“已保存”。大约 2-3 晚后,我无法弄清楚发生了什么。不确定这是否是实现结果的最佳解决方案。

此外,如果我终止该应用程序并重新加载,一切又好了。

我尝试了 this 答案的一个版本,但我对编码仍然是新手,也许我没有做正确的事情,因为它根本不起作用(在核心数据中显示了所有结果)。

感谢任何帮助 - 花了几天时间试图解决这个问题。

import SwiftUI
import CoreData

struct HomeScreenView: View {
    @EnvironmentObject var backgroundSet: Background
    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(entity: Entry.entity(),
        sortDescriptors: [NSSortDescriptor(keyPath: \Entry.date, ascending: true)], predicate: nil, animation: .default)

private var entries: FetchedResults<Entry>

        init(){
            var calendar = Calendar.current
            calendar.timeZone = NSTimeZone.local
            let dateFrom = calendar.startOfDay(for: Date()) // eg. 2016-10-10 00:00:00
            let dateTo = calendar.date(byAdding: .day, value: 1, to: dateFrom)
            let predicate = NSPredicate(format : "date <= %@ AND  date >= %@", dateTo! as CVarArg, dateFrom as CVarArg)
            self._entries = FetchRequest(
                entity: Entry.entity(),
                sortDescriptors: [NSSortDescriptor(keyPath: \Entry.date, ascending: false)],
                predicate: predicate)
        }

 @State var presentSheet = false
    @State private var today : Date = Date()

 var body: some View {

        NavigationStack {
            ZStack {

if entries.count == 0 {
                        Button("Please make an entry?") {
                            presentSheet = true
                            //refresh.toggle()
                        }
                        .frame(minWidth: 250, minHeight: 50, alignment: .center).padding()
                        .cornerRadius(40)
                        .padding()
                    } else {
                        NavigationLink(destination: HistoryView()) {
                            VStack {
                                Text("Saved for today.")
                                Text("Click here to view history.")
                            }
                        }
                        .frame(minWidth: 250, minHeight: 50, alignment: .center).padding()
                        .cornerRadius(40)
                        .padding()
                    }

            }
            .sheet(isPresented: $presentSheet) {
                AddEntryView()
                    .presentationDetents([.medium])   
            }

这里是一份坚持:

import CoreData

struct PersistenceController {
    static let shared = PersistenceController()

    static var preview: PersistenceController = {
        let result = PersistenceController(inMemory: true)
        let viewContext = result.container.viewContext
        for _ in 0..<10 {
            let newEntry = Entry(context: viewContext)
            newEntry.timestamp = Date()
        }
        do {
            try viewContext.save()
        } catch {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            let nsError = error as NSError
            fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
        }
        return result
    }()

    let container: NSPersistentContainer

    init(inMemory: Bool = false) {
        container = NSPersistentContainer(name: "Express_Gratitude")
        if inMemory {
            container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
        }
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {              
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        container.viewContext.automaticallyMergesChangesFromParent = true
    }
}

这是@main中的内容

var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}

从上面的链接,我尝试了这个版本,但没有用。我可能完全错误地实施了这个……接受教育和建议以实现结果。

import SwiftUI
import CoreData

struct HomeScreenView: View {
    @EnvironmentObject var backgroundSet: Background
    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(entity: Entry.entity(),
        sortDescriptors: [NSSortDescriptor(keyPath: \Entry.date, ascending: true)], predicate: nil, animation: .default)
    
    private var entries: FetchedResults<Entry>
    
    init(){
        // Get the current calendar with local time zone
        var calendar = Calendar.current
        calendar.timeZone = NSTimeZone.local
        // Get today's beginning & end
        let dateFrom = calendar.startOfDay(for: Date()) // eg. 2016-10-10 00:00:00
        let dateTo = calendar.date(byAdding: .day, value: 1, to: dateFrom)
        // Note: Times are printed in UTC. Depending on where you live it won't print 00:00:00 but it will work with UTC times which can be converted to local time
        // Set predicate as date being today's date
        let fromPredicate = NSPredicate(format: "%@ >= %K", dateFrom as NSDate, #keyPath(Entry.date))
        let toPredicate = NSPredicate(format: "%K < %@", #keyPath(Entry.date), dateTo! as NSDate)
        let datePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [fromPredicate, toPredicate])
        self._entries = FetchRequest(
            entity: Entry.entity(),
            sortDescriptors: [NSSortDescriptor(keyPath: \Entry.date, ascending: false)],
            predicate: datePredicate)
    }

    @State var presentSheet = false
    @State private var today : Date = Date()
swift swiftui core-data filtering predicate
© www.soinside.com 2019 - 2024. All rights reserved.