I've reduced my code to just a dozen lines for the sake of this question. I linked fetchedResultsController to the jsqMessagesViewController framework.
What the app does is when you press the send button, it inserts an object into context, which activates .Insert
of fetchedResultsController.
For some reason, every time I insert into the collection View it reloads every single thing in the collection view. This is causing a TON of bugs, and I can't tell if it's something I'm doing wrong, if its the JSQ framework itself, or if this is normal?
Anyways, here is my entire code. It is not long, and if you're familiar code data in swift, this should be a breeze for you to read.
class ChatController: JSQMessagesViewController, NSFetchedResultsControllerDelegate {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
lazy var fetchedResultsControler: NSFetchedResultsController<NSFetchRequestResult> = {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Message")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timestamp", ascending: true)]
let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.context, sectionNameKeyPath: nil, cacheName: nil)
frc.delegate = self
return frc
}()
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
if type == .insert {
collectionView.insertItems(at: [newIndexPath!])
scrollToBottom(animated: true)
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.senderId = ""
self.senderDisplayName = ""
do {
try fetchedResultsControler.performFetch()
}
catch { }
}
override func didPressSend(_ button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: Date!) {
let message = NSEntityDescription.insertNewObject(forEntityName: "Message", into: context) as! Message
message.text = text
message.timestamp = Date() as NSDate?
}
override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageDataForItemAt indexPath: IndexPath!) -> JSQMessageData! {
let msg : Message = fetchedResultsControler.object(at: indexPath) as! Message
let messageData = JSQMessage(senderId: senderId, displayName: senderDisplayName, text: msg.text)
return messageData
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return (fetchedResultsControler.sections?[0].numberOfObjects)!
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = super.collectionView(collectionView, cellForItemAt: indexPath) as! JSQMessagesCollectionViewCell
cell.layer.shouldRasterize = true
cell.layer.rasterizationScale = UIScreen.main.scale
return cell
}
override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAt indexPath: IndexPath!) -> JSQMessageBubbleImageDataSource! {
let bubbleFactory = JSQMessagesBubbleImageFactory()
return bubbleFactory?.outgoingMessagesBubbleImage(with: .black)
}
override func collectionView(_ collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAt indexPath: IndexPath!) -> JSQMessageAvatarImageDataSource! {
return nil
}
}