введите описание изображения здесь Я создал простой пример своей проблемы, которую я не могу найти решение.
В делегате приложения имеется стек основных данных со статической переменной для извлечения постоянного контейнера. Я получаю доступ к этой переменной в обоих контроллерах представления и получаю moc (persistantContainer.viewController), используемый каждым контроллером.
Я создал две сущности (Коллекция и Колода) в основных данных. Каждый с одним атрибутом (title: String). Коллекция имеет отношение «ко многим», а Deck и Decks - «to-one». У меня есть два контроллера таблицы просмотра, каждый с контроллером извлеченных результатов. На панели навигации есть кнопка добавления для каждого контроллера представления, которая позволяет пользователю добавлять коллекцию или колоду (соответственно). Я могу выполнить коллекцию добавления и заставить методы делегата fetchedResultsController запускать и отображать добавленный элемент просто отлично. При выборе элемента строки для коллекций я обращаюсь ко второму контроллеру табличного представления для отображения колод для выбранной коллекции.
У fetchedResultsController во втором TableViewController есть предикат, который проверяет соответствие коллекций колод таким же, как и выбранная коллекция. Я хочу, чтобы отображались только те колоды, которые являются частью выбранной коллекции.
Эта часть работает нормально, но когда пользователь выбирает добавить колоду, он добавляется, но не запускает методы NSFetchedResultsControllerDelegate для отображения колоды в виде таблицы. Если я вернусь к представлению коллекций, затем снова выберу ту же коллекцию, колода появится. Так что я знаю, что это было добавлено.
Проблема состоит из двух частей:
1) Почему NSfetchedResultsControllerDelegate не запускается
2) Я хочу, чтобы пользователь вводил имена Коллекции и Колоды при добавлении через UIAlertController с текстовым полем. Я настроил это, и это работает для CollectionViewController, но я не могу заставить его работать в DecksViewController. Я действительно не знаю, в каком потоке мне следует запускать код или если обработчик AlertAction находится в фоновом потоке.
За последние два дня я просмотрел этот форум и форум Apple на предмет любой помощи.
Вещи, которые я пробовал. Диспетчер главной очереди, передавая управляемый objectID, получая управляемый объектный текст из переданного объекта коллекции, удаляя предикат все вместе, чтобы посмотреть, смогу ли я заставить его работать. Ничто не дает ожидаемого результата.
var collection: CollectionMO!
private lazy var frc: NSFetchedResultsController<DeckMO> = {
let fetchRequest:NSFetchRequest<DeckMO> = DeckMO.fetchRequest()
let sort1 = NSSortDescriptor(key: "title", ascending: true)
fetchRequest.sortDescriptors = [sort1]
fetchRequest.predicate = NSPredicate(format: "collection == %@", collection)
let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: viewContext, sectionNameKeyPath: nil, cacheName: nil)
frc.delegate = self
return frc
}()
@IBAction func addDeck(_ sender: UIBarButtonItem) {
nameDeck() // this is the preferred method and remaining code in this action test code to get it working
let newDeck = DeckMO(context: viewContext)
newDeck.title = "Deck \((frc.fetchedObjects?.count)! + 1) in \(collection.title ?? "")"
collection.addToDecks(newDeck)
}
private func nameDeck(_ deck:DeckMO? = nil) {
let alert = UIAlertController.init(title: deck?.title != nil ? "Retitle Deck:" : "Enter New Deck Title",
message: deck?.title ?? "", preferredStyle: .alert)
alert.addTextField(configurationHandler: { (textField: UITextField) in
textField.placeholder = deck?.title ?? "Enter Deck Title"
})
alert.addAction(UIAlertAction.init(title: "Cancel", style: .destructive, handler: nil))
alert.addAction(UIAlertAction.init(title: "Save", style: .default, handler: { action in
if let text1 = alert.textFields?.first, text1.hasText, text1.text != deck?.title {
if let updateDeck = deck {
updateDeck.title = text1.text
} else {
DispatchQueue.main.async {
let newDeck = DeckMO(context: self.viewContext)
newDeck.title = text1.text
newDeck.collection = self.collection
}
}
}
}))
self.present(alert, animated: true)
}
DeckViewController должен отображать колоду, добавленную сразу после добавления, а DeckViewController должен отображать только колоды выбранной Коллекции из предыдущего viewController.