无法正确创建托管对象并将其保存在核心数据中

时间:2019-01-09 20:36:09

标签: swift core-data nsfetchedresultscontroller uialertcontroller

enter image description here我创建了一个我无法找到解决方案的简单示例。

App委托中有一个核心数据堆栈,带有一个静态var来检索持久性容器。我在两个视图控制器中都访问了此var,并获得了每个控制器使用的moc(persistantContainer.viewController)。

我在核心数据中创建了两个实体(Collection和Deck)。每个都有一个属性(标题:字符串)。集合与Deck和Decks有着“多对多”的关系,逆向是“多对一”。我有两个tableview控制器,每个都有一个获取的结果控制器。每个视图控制器在导航栏中都有一个添加按钮,允许用户分别添加一个Collection或一个Deck。我可以执行add Collection并让fetchedResultsController委托方法启动并显示添加的项目。为“收藏夹”选择行项目时,我选择转到第二个tableview控制器以显示所选收藏夹的卡片组。

第二个TableViewController中的fetchedResultsController具有一个谓词,用于检查Decks的集合关系是否与所选集合相同。我只希望显示所选集合中的套牌。

这部分工作正常,但是当用户选择添加Deck时,它会被添加,但不会触发NSFetchedResultsControllerDelegate方法以在表格视图中显示卡片组。如果我滑回到收藏夹视图,然后再次选择相同的收藏夹,则现在会显示甲板。所以我知道它被添加了。

问题有两个部分: 1)为什么NSfetchedResultsControllerDelegate不触发 2)我希望用户在通过带有文本字段的UIAlertController添加时输入Collection和Deck名称。我已经设置好了它,它适用于CollectionViewController,但无法在DecksViewController中使其工作。我真的不知道我应该在哪个线程上运行代码,或者AlertAction处理程序是否在后台线程中。

最近两天,我一直在这个论坛和Apple的论坛中寻找帮助。

我尝试过的事情。 Main Que Dispatch,传递托管对象ID,从传递的集合对象中获取ManagedObjectcontext,一起删除谓词,以查看是否可以使它起作用。没有得到我期望的结果。

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中所选集合的Decks。

0 个答案:

没有答案