3

I'm trying something but I could not achieve the result I want and I'm asking for your help because I've struggled a lot.

I have a list of document and I want to display each of them using Sections, so for documents from June to make a section Like June 2022, for documents from August August 2022. Basically, I want to display all the documents, but each document to be displayed in the correct Month by using a section.

I'll share bellow what I tried.

The screen :

struct DocumentsListScreen: View {
    @ObservedObject var viewModel : DocumentsViewModel
    init(viewModel: DocumentsViewModel)
    {
        self.viewModel = viewModel
        viewModel.fetchDocuments()
    }
    var body: some View {
        if viewModel.presentingLoader {
            LoaderView()
        }
        else {
            List {
                ForEach(viewModel.getUniqueDates(), id: \.self) { date in
                    Section(header: Text(viewModel.prettyDate(date))
                        .foregroundColor(.red)) {
                            ForEach(viewModel.arrayByDate(), id: \.idid) { doc in
                                VStack {
                                    Text(doc.category)
                                    Text(doc.title)
                                    Text(doc.isPersonDoc)
                                    Text(doc.isPersonDoc)
                                    Text(doc.date)
                                }
                            }
                        }
                }
            }
        }
    }
}

The View Model :

class DocumentsViewModel : ObservableObject {
    @Injected private var documentsUseCase: DocumentsUseCaseProtocol
    @Published var documentsAssetsData: [DocumentsAssetsData] = []
    @Published public var presentingLoader = true
    var newArray: [String] = []
    
    func fetchDocuments() {
        documentsUseCase.performDocumentsRequest { [weak self] result in
            switch result {
            case .success(let response):
                self?.documentsAssetsData = response
                self?.presentingLoader = false
            case .failure(_):
                break
            }
        }
    }
    func prettyDate(_ date: String) -> String {
        let dateFormatterGet = DateFormatter()
        dateFormatterGet.dateFormat = "yyy.MM.dd"
        
        let dateFormatterPrint = DateFormatter()
        dateFormatterPrint.dateFormat = "MMMM yyyy"
        
        let formattedDate: Date? = dateFormatterGet.date(from: date)
        
        guard let date = formattedDate else {
            return ""
        }
        
        return dateFormatterPrint.string(from: date)
    }
    
    func getUniqueDates() -> [String]{
        for item in documentsAssetsData {
            newArray.append(prettyDate(item.date))
        }
        let uniqueDates = newArray.compactMap { $0 }
        let datesArray = Array(Set(uniqueDates))
        
        let formatter = DateFormatter()
        let output = datesArray
            .map { (string: $0, date: formatter.date(from: $0)) }
            .sorted {
                guard let date1 = $0.date else { return true }
                guard let date2 = $1.date else { return false }
                return date1 > date2
            }.map { $0.string }
        return output
    }
    
    func arrayByDate() -> [DocumentsAssetsData]{
        let items = documentsAssetsData.filter {prettyDate($0.date) == getUniqueDates().first}
        return items
    }
    
}

The json file that correspond to the Model I'm using, maybe it will help.

[
{
        "idid": "1",
        "title": "Document nr.4",
        "category" : "Tax documents",
        "date": "2022-08-08",
        "isPersonDoc": false,
        "productId": "4",
        "personName": "Marie-Ange Schramm",
        "productName": "Product Name 4",
        "bpNr": 121324600
      },
    {
        "idid": "2",
        "title": "Document nr.5",
        "category" : "Tax documents",
        "date": "2022-08-09",
        "isPersonDoc": false,
        "productId": "5",
        "personName": "Alessia Ackermann",
        "productName": "Product Name 5",
        "bpNr": 121324700
      }
]

Also, another problem is that the title of the section is missing ( I don't know why ), but I tried to debug it and there are datas there .

Debugging the output for getUniqueDates()

Printing description of output:
▿ 4 elements
  - 0 : "Juli 2022"
  - 1 : "Juni 2022"
  - 2 : "August 2022"
  - 3 : "Mai 2022"

I'll share here a picture with the actual state of the List. Check image

Thanks a lot !

  • A grouping in a dictionary might work but there is so much extra code that it is hard to help specifically. Try reducing your code to the least amount necessary to create a working sample. You will get better responses. – lorem ipsum Oct 19 '22 at 20:19
  • @loremipsum I reduced it a little bit, thanks for the suggestion ! – Ionut Motica Oct 19 '22 at 20:27
  • I'm very suspicious that the picture you are showing represents your code. You have **2** `Text(doc.isPersonDoc)` in `DocumentsListScreen`, and your date format of your json data is "yyyy-MM-dd" not what you use "yyy.MM.dd". – workingdog support Ukraine Oct 19 '22 at 22:40
  • Does this answer your question? [How to properly group a list fetched from CoreData by date?](https://stackoverflow.com/questions/59180698/how-to-properly-group-a-list-fetched-from-coredata-by-date) Or, this: https://stackoverflow.com/questions/73733910/swiftui-sorting-a-structured-array-and-show-date-item-into-a-section-header – workingdog support Ukraine Oct 19 '22 at 22:44

0 Answers0