badoo / badoo/Chatto

Performance issues when using CoreData as messages dataSource

Open
#290 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Swift
Stars
4.6k
Forks
588
PR merge metrics
No merged PRs in 30d

Description

Hi!
I'm using `CoreData` to store messages for chat room. When users taps on specific chat cell, app fetches messages for this chat from `CoreData` and create `ChatItemProtocol` items, which is then added to `dataSource`. It looks like this:

```swift
func messagesForCurrentChat(chat_id: String) -> [ChatItemProtocol] {
var messages = [ChatItemProtocol]()
let fetchRequest: NSFetchRequest = Message.fetchRequest()
let predicate = NSPredicate(format: "chat_id like %@", chat_id)
let sd = NSSortDescriptor(key: "timestamp", ascending: true)
let sortDescriptors = [sd]
fetchRequest.predicate = predicate
fetchRequest.sortDescriptors = sortDescriptors
fetchRequest.fetchBatchSize = 10
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,
managedObjectContext: self.coreDataStack.managedContext,
sectionNameKeyPath: nil,
cacheName: nil)
do {
try fetchedResultsController.performFetch()
for object in fetchedResultsController.fetchedObjects! {
if !object.isMedia {
let textMessage = createTextMessageModel(object.id!, sender: object.sender!, text: object.textContent!, date: object.timestamp! as Date, isIncoming: object.incoming, status: Int(object.status))
messages.append(textMessage)
} else {
if let url = object.mediaContent {
let photoMessage = createPhotoMessageModel(object.id!, sender: object.sender!, date: object.timestamp as! Date, image: nil, imageUrl: url, size: CGSize(width: 300.0, height: 300.0), isIncoming: object.incoming, status: Int(object.status))
messages.append(photoMessage)
}
}
}
} catch let error as NSError {
print("Fetching error: \(error), \(error.userInfo)")
}
return messages
}
```

So, then in `prepare(for segue)` in ChatListViewController:
```swift
class ChatListViewController: UIViewController {
...
...
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ChatSegue" {
let controller = segue.destination as! ChatViewController
controller.selectedChat = self.selectedChat
let messagesForChat = messagesForCurrentChat(chat_id: self.selectedChat.uid!)
let dataSource = SlidingDataSource(messages: messagesForChat, pageSize: 50)
controller.dataSource = dataSource
}
}
```
And when I have more then 100 messages in chat, it looks some time to open chat with messages (if compare to ChattoApp when opening 10000 messages chat). So, my question is, how to optimise this chat opening issues?
Maybe I need to fetch not all messages for this chat, but only 50 (the same as `pageSize` in `SlidingDataSource`), and when I scroll up asynchronously fetch messages from `CoreData` and add them to `dataSource`? But is it possible to dynamically add messages to `dataSource` to the top?
Anyway, thanks for any help, this bug is tormenting me for few month :)

Contributor guide

Open the contributing guide

Research direction

Start with messagesForCurrentChat in ChatListViewController and trace how its CoreData results are passed to SlidingDataSource and ChatViewController during prepare(for:). Reproduce the delay with a chat containing more than 100 messages, then define and validate an agreed loading behavior, including whether messages can be added at the top while scrolling.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
mobile, performance
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.