Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sectioned Results with Empty Sections #8495

Open
jadar opened this issue Feb 22, 2024 · 5 comments
Open

Sectioned Results with Empty Sections #8495

jadar opened this issue Feb 22, 2024 · 5 comments
Assignees
Labels
Importance:Workaround O-Community SDK-Use:Local T-Enhancement Waiting-For-Reporter Waiting for more information from the reporter before we can proceed

Comments

@jadar
Copy link

jadar commented Feb 22, 2024

Problem

Sometimes you need to have a sectioned UITableView that shows a section even if there are no cells in that section. The current behavior of SectionedResults is that it only has a section if there is an object in that section. If you try to use multiple Results with observers, you'll end up with NSInternalInconsistencyExceptions. It triggers the table to update for one section before the other, but it still compares the before and after counts of all sections in the update for the one. Also, if you try to force an "empty" section with SectionedResults, the observation updates will be inconsistent and impossible to manage.

Solution

It would be great to be able to supply either an array of sections, or use another query to define the sections.

Alternatives

I have three different workarounds, which none of them are great.

  1. One UITableView with SectionedResults and hard-coded sections.

Hard-code the number of sections, observe changes, and hard-reload UITableView. The problem is that you can't use batch updates, because the section insert/deletion updates don't match the hard-coded sections. It's also not enough to ignore the section insertion/deletion updates, because row updates are also not always consistent and it causes UITableView to raise NSInternalInconsistencyException.

  1. One UITableView with two Results.

Use one Results per section. This doesn't work, and if I understand correctly is the reason that SectionedResults exists. Responding to changes in one section causes the counts to be checked in other sections, before those changes are processed, and UITableView raises NSInternalInconsistencyException.

  1. Two UITableView with two Results.

Position multiple UITableViews into a single UIScrollView, each with their own Results. This is the only one that doesn't crash because it follows the intended use case of Results. However, now you have to deal with correctly sizing multiple UITableViews in a view, which is also a pain. At least it doesn't crash though!

How important is this improvement for you?

I would like to have it but have a workaround

Feature would mainly be used with

Local Database only

Copy link

sync-by-unito bot commented Feb 22, 2024

➤ PM Bot commented:

Jira ticket: RCOCOA-2295

@Jaycyn
Copy link

Jaycyn commented Feb 22, 2024

Question: To me, an empty section would just be a section header with no rows following. Is that the case here?

It would be helpful to see a minimal example of the issue so we can see how the sections are being defined and what an 'empty' section would look like.

@jadar
Copy link
Author

jadar commented Feb 22, 2024

Question: To me, an empty section would just be a section header with no rows following. Is that the case here?

It would be helpful to see a minimal example of the issue so we can see how the sections are being defined and what an 'empty' section would look like.

It could be. For example, if you had a hierarchy of data (like a file system) and had a directory without childrens, then you would have an empty section.

The case in our app is that we want to have sections based on that "status" of an object: "Paused" and "Finished". Here are screenshots that depict it.

Simulator Screenshot - iPhone 15 Pro - 2024-02-22 at 14 42 37 MediumSimulator Screenshot - iPhone 15 Pro - 2024-02-22 at 14 42 40 Medium

@Jaycyn
Copy link

Jaycyn commented Feb 22, 2024

Allow me to think through this at kind of a high level here.

It's up to you, the developer to determine how 'sections' are derived. For example, if you have a contact list and want sections by the first letter representing each contact it would be something like this in Swift

@ObservedSectionedResults(Contact.self, sectionKeyPath: \.firstLetter)

or suppose you want to have sections representing States in the US that are stored in your database.

@ObservedSectionedResults(USState.self, sectionKeyPath: \.stateName)

In other words, the section headers are derived from the data itself. If there is no contact starting with "Z" then there's no "Z" section. If there's no state "Florida", there would be no section "Florida".

I would think the simple solution is to pre-populate your database with objects that you know will represent the headers, but with nil or empty properties and a property to indicate if it's a section header or not.

class Contact: Object {
   @Persisted var firstLetter = ""
   @Persisted var contactName = ""
   @Persisted var isHeader = false
}

let contactA = Contact()
contactA.firstLetter = "A"
contactA.isHeader = true

let contactB = Contact()
contatB.firstLetter = "B"
contactB.isHeader = true

then when the app starts, ensure all contacts that are headers are written which forces every section to have a header whether or not there's any actual rows within that header.

From there - just ensure queries exclude headers from their results.

Just a thought!

@jadar
Copy link
Author

jadar commented Feb 24, 2024

That might work. It feels forced but might be a viable workaround. I'll play with it and see how it works.

@sync-by-unito sync-by-unito bot added the Waiting-For-Reporter Waiting for more information from the reporter before we can proceed label Mar 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Importance:Workaround O-Community SDK-Use:Local T-Enhancement Waiting-For-Reporter Waiting for more information from the reporter before we can proceed
Projects
None yet
Development

No branches or pull requests

3 participants