NSFetchedResultsController Не обновляет представление коллекции автоматически
У меня есть функция didPressSend, которая берет текст, который был написан в текстовом представлении, и вставляет его в контекст в виде строки. После вставки в контекст NSCetchedResultsController's DidChangeContent обнаруживает, что что-то было вставлено в контекст, и соответствующим образом автоматически обновляет представление коллекции (имейте в виду, что DidChangeContent абсолютно пуст). Вот код, который у меня есть только для этой части. (Создать сообщение с текстом - это функция, которая вставляется в контекст).
func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String! ,senderDisplayName: String!, date: NSDate){
let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
createMessageWithText(text, friend: friend!, context: moc, date: date)
do {
try context.save()
} catch let err {
print(err)
}
}
private func createMessageWithText(text: String, friend: Friend, context: NSManagedObjectContext, date: NSDate, isSender: Bool = false) -> Mesages {
let message = NSEntityDescription.insertNewObjectForEntityForName("Mesages", inManagedObjectContext: context) as! Mesages
message.user = friend
message.text = text
message.timestamp = date
message.isSender = isSender
friend.lastMessage = message
return message
}
}
После вставки в контекст didChangeContent обнаруживает его как таковой и автоматически обновляет представление коллекции:
lazy var fetchedResultsControler: NSFetchedResultsController = {
let fetchRequest = NSFetchRequest(entityName: "Mesages")
fetchRequest.fetchBatchSize = 50
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timestamp", ascending: true)]
fetchRequest.predicate = NSPredicate(format: "user.id = %@", self.friend!.id!)
let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
frc.delegate = self
return frc
}()
func controllerDidChangeContent(controller: NSFetchedResultsController) {
}
Странная часть в том, что в DidChangeContent нет абсолютно ничего, что, по-видимому, отвечает за заполнение collection View, имейте в виду, что я заполняю collection View количеством объектов в fetchResultsController как таковым:
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) ->
Int {
if let count = fetchedResultsControler.sections?[0].numberOfObjects {
return count
}
return 0
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath) as! JSQMessagesCollectionViewCell
return cell
}
override func collectionView(collectionView: JSQMessagesCollectionView!, messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {
let msg : Mesages = fetchedResultsControler.objectAtIndexPath(indexPath) as! Mesages
let messageData = JSQMessage(senderId: "" , displayName: "Me", text: msg.text)
return messageData
}
У меня также есть прослушиватель из firebase, который, когда мне отправляют сообщение, сразу же обнаруживает его, вставляет в контекст, сохраняет, nsfetchResultsController обнаруживает это и запускает didChangeContent. Странная часть в том, что в этом случае он не обновляется автоматически, пока я не поместил collection View.reloadData в didChangeContent. Однако мне не нужно помещать collection View.reloadData для didPressSend, так как он волшебным образом автоматически обновляется сам по себе. Код для прослушивателя firebase, который вставляет в контекст так же, как didPressSend, выглядит следующим образом: (Создать сообщение с текстом - это функция, которая вставляется в контекст).
ref2.observeEventType(.ChildAdded, withBlock: {(snapshot2) in
let messageId = snapshot2.key
//first message ID out of 20.
let messagesRef = FIRDatabase.database().reference().child("messages").child(messageId)
messagesRef.observeSingleEventOfType(.Value, withBlock: { (snapshot) in
let dictionary = snapshot.value as! [NSObject: AnyObject]
let timestamp = dictionary["timestamp"] as! NSNumber
let doubleTimestamp = Double(timestamp)
let date = NSDate(timeIntervalSinceReferenceDate: (doubleTimestamp))
self.createMessageWithText(dictionary["text"]! as! String, friend: friend, context: context, date: date, isSender: true)
do {
try context.save()
}
catch {
print(error)
}
private func createMessageWithText(text: String, friend: Friend, context: NSManagedObjectContext, date: NSDate, isSender: Bool = false) -> Mesages {
let message = NSEntityDescription.insertNewObjectForEntityForName("Mesages", inManagedObjectContext: context) as! Mesages
message.user = friend
message.text = text
message.timestamp = date
message.isSender = isSender
friend.lastMessage = message
return message
}
Тем не менее, я не уверен, почему и как заполнение collection View заполняется NSfetchedResultsController. (Меня действительно беспокоит, что DidPressSend заполняет представление коллекции без каких-либо данных перезагрузки). Также ДРУГАЯ ошибка, которая идет с этим, если я удаляю didChangeContent, который, как вы можете видеть, содержит НИЧЕГО, didPressSend останавливает автообновление. И когда я добавляю пустой didChangeContent, коллекция View начинает автообновление (только для didpressSend).
0 ответов
Реализуйте ниже метод делегата, и collectionView или TableView обновят синхронизацию. как только получу новые данные.
extension ViewController: NSFetchedResultsControllerDelegate {
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
}
}