Модель для поиска заметок по дате

#swift #swiftui #swift-dictionary

#swift #swiftui #swift-словарь

Вопрос:

Как моделировать заметки, чтобы я мог искать их после по датам? как на картинке.

Во-первых, я думал о словаре с ключом типа Date ; но у меня это не сработало. Итак, я попробовал следующий String формат:

«04-28-2020» — календарь США

«28-04-2020» — Другой календарь

Одна из проблем — если телефон меняет стиль даты (зависит от региона), ключи остаются в словаре, но к ним больше не обращаются…

Моя интуиция, что это должен быть словарь, но каков устойчивый способ создания такой модели? Может ли это быть массив заметок [Note] без ключей?

введите описание изображения здесь

 struct Note: Codable, Identifiable {
    let id = UUID()
    var date: Date
    var title: String
    var description: String
    
    var dateString: String {
        let df = DateFormatter()
        df.dateStyle = .short
        df.timeStyle = .medium
        return df.string(from: date)
    }
    
    // method returns "key" to be used in dictionary
    static func dateKey(for date: Date) -> String {
        let df = DateFormatter()
        df.dateStyle = .short
        return df.string(from: date)
    }
}

class NotesOrganizer: ObservableObject {
    
    // @Published var notes = [Note]() - tried initially
    @Published var notesDictionary = [String : [Note]]()
}

struct ContentView: View {
    @State private var title = ""
    @State private var description = ""
    @ObservedObject var notesOrganizer = NotesOrganizer()
    
    var body: some View {
        NavigationView {
            VStack {
                Button("Save note") {
                   
                        let key = Note.dateKey(for: Date())
                        notesOrganizer.notesDictionary[key]?.append(Note(date: Date(), title: title, description: description)) 
?? (notesOrganizer.notesDictionary[key] = [Note(date: Date(), title: title, description: description)])
                        
                        print("Date Key: (Note.dateKey(for: Date()))")    
                }
                
                
                NavigationLink(destination: DetailView(notesOrganizer: notesOrganizer)) 
                {
                    
                    Text("Log history ->")
                        .foregroundColor(.purple)
                        .underline()
                }
            }
            .navigationBarHidden(true)

        }
        
    }
    
    init() {
        UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
        UINavigationBar.appearance().shadowImage = UIImage()
    }

}
 

Просмотр деталей()

 extension Date {
        var tomorrow: Date? {
            return Calendar.current.date(byAdding: .day, value: 1, to: self)
        }
        
        var yesterday: Date? {
            return Calendar.current.date(byAdding: .day, value: -1, to: self)
        }
}

struct DetailView: View {
    @ObservedObject var notesOrganizer: NotesOrganizer
    @State private var dayLabel: String = Note.dateKey(for: Date())
    @State private var chosenDate = Date()
    

    var body: some View {
        VStack {
            HStack {
                Button(action: {
                    chosenDate = chosenDate.yesterday!
                    dayLabel = Note.dateKey(for: chosenDate)
                }, label: {
                    Image(systemName: "chevron.left")
                })
                
                Text(dayLabel)
                
                Spacer()
                
                Button(action: {
                    chosenDate = chosenDate.tomorrow!
                    dayLabel = Note.dateKey(for: chosenDate)
                }, label: {
                    Image(systemName: "chevron.right")
                })
                
            }
            .padding([.horizontal,.bottom])
            
            List{
                ForEach(notesOrganizer.notesDictionary[day] ?? []) { note in
                    HStack {
                        VStack(alignment:.leading) {
                            Text(note.title)
                            Text(note.description)
                        }.multilineTextAlignment(.leading)
                        Spacer()
                        Text(note.dateString)
                    }
                }.onDelete(perform: removeItems)
            }
            .navigationBarTitle("", displayMode: .inline)
                
            
            Spacer()
        }
 

Комментарии:

1. Вы могли бы использовать основные данные. Создайте модель заметок, дайте ей атрибуты, связанные с датой: конечно, объект даты, но также, возможно, строку, представляющую «раздел месяца» или «раздел дня», который вам нужен, например, note.section (т. Е. «2020/12/31»), или даже простые целые числа. Нравится: примечание. год (2020), примечание.месяц (12), примечание.день (31), примечание.час, примечание.минута и т.д. Затем вы должны выполнить поиск с помощью NSPredicate Core Data по этим атрибутам.

2. @EricAya будет ли это также работать для переключения дат, как на картинке? и словарь не нужен? Как и каждый раз, когда пользователь переключает метку даты, он будет выполнять поиск по данным из CoreData?

3. Если вы еще не знакомы с Core Data, я предлагаю использовать простую структуру заметок с атрибутами даты, как я объяснил, и привести ее в соответствие с Codable и сохранить массив заметок в формате JSON. Это легко сделать, и затем вы сможете изучить, как выполнять поиск по ним, .filter например, с помощью. Если через некоторое время вы увидите, что вам нравится эта система, перейдите к Core Data, которая будет «профессиональной» версией. // Всегда сохраняйте все даты как UTC (и / или используйте формат ISO, например «2020/12/31» для хранения строк дат). Затем отформатируйте дату, используя языковой стандарт / календарь пользователя, прежде чем отображать ее.