Search code examples
iosswiftcore-datansfetchedresultscontrollermessage

Grouping messages similar to iPhone Message app


In our iOS application, we are using core data and tied it with a table view using NSFetchedResultsController. The app is about "Chat" feature.

UI is same as that of iPhone "Messages" app. When we tap on a message, it displays the history and all the history grouped with time. The logic behind it is, if previous message and current message are received with a gap of 1 hr, then date & time stamp will be displayed over recent message.

My question is, how can I group the messages and fetch them so that I can show the date & time stamp as well as sender and receiver messages.


Solution

  • There are four types of message cells type - regular, group-start, group-middle, group-end. A group-start message is more than a hour after the last one but less than an hour to the next one. group-middle is less than an hour from the one before and after. group-end is close to the one before it, but more than hour to the one after it. regular is more than a hour before and after it.

    There are two parts of this project. One is to display each type of cell correctly. The other is figure-out which type each message is. I assume you can figure out the UI stuff yourself (different padding, for each one, regular and group-start show the time, not rounding some corners, etc).

    For each message to figure out its type, is not that hard - just look at the message before it and after it. It can be done in a single run through of the results - O(n). It could also be done lazily with a cache (ie each time a cell load check the message before and after it - save the answer in the cache for next time). If the cell sizes are different for different types then it make cause some weird jumping with estimatedRowHeight. You could also store the results of the type into core-data after you calculate it.

    Be careful when a message is inserted to invalidate and recalculate the message cell type for the one above and below it. Also when calculating the message cell type account for situations where there isn't a next or previous cell.

    I think you were hoping for some core-data magic - like some cleaver trick with sectionIndexKey. But it is really much more straight forward of just running through the array and calculating it.

    Update: Just to make it clear: don't use sections. Keep all the cells in one section. Just add the time to the top of the cell for the cell type group-start. It is a lot easier than dealing with sections especially when there are inserts that can cause and earlier cell to change from normal to group-start.