NSFetchedResultsController didChangeContentWith 使用成功保存对象的临时 ID

问题描述 投票:0回答:1

背景: 我有一个具有两个核心数据实体(资产和组)的应用程序,具有一对多关系(一个组包含许多资产)。 CollectionView 获取组项目并将它们用作部分,资产是各个单元格。当用户保存新条目时,会调用 didChangeContentWith 方法,但新资产项使用“临时 ID”。

问题/崩溃: UI 显示正常,但是当用户点击单元格时,应用程序崩溃,因为它找不到具有该 NSManagedObjectID 的对象。

代码:

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) {
    
    var newSnapshot = NSDiffableDataSourceSnapshot<String, NSManagedObjectID>()
   
    if let sections = controller.sections {
       
        // Iterate through the fetched sections (groups)
        for sectionInfo in sections {
            if let group = sectionInfo.objects?.first as? Group {
                
                // Append the section (group name) to the snapshot
                newSnapshot.appendSections([group.name!])
                
                // Get the objects associated with this Group
                if let assets = group.assets {
                    let assetIDs = assets.map{ $0.objectID }
                    
                    for id in assetIDs {
                        print("<<<< ID temp: \(id.isTemporaryID)")
                    }
                    
                    // Append the Asset objects as items within the section (group)
                    newSnapshot.appendItems(assetIDs, toSection: group.name)
                }
            }
        }
    }
    
    // Apply the snapshot to the UICollectionViewDiffableDataSource
    dataSource.apply(newSnapshot, animatingDifferences: true)
}

保存功能:

 context.performAndWait { [unowned self] in 
        let _ = generateOrUpdateAsset(with: id, name: self.name, priority: self.priority, comments: self.comments, context: context)
        
        // Here the temp id is used
        do {
            try context.save()
            // Here the temp id is not used

        } catch {
            print("Failed to saving test data: \(error)")
        }
    }

获取功能:

 func performCoreDataFetch(){
    if let context = self.context {
        let fetchRequest = Group.fetchRequest()
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: false)]
        fetchRequest.relationshipKeyPathsForPrefetching = ["asset"]
        
        let predicate = NSPredicate(format: "ANY assets != nil")

        fetchRequest.predicate = predicate

        fetchResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,
                                                            managedObjectContext: context,
                                                            sectionNameKeyPath: "name",
                                                            cacheName: nil)
        fetchResultsController.delegate = self
        try! fetchResultsController.performFetch()
    }
}

非常感谢您的帮助!

swift core-data uicollectionview nsfetchedresultscontroller diffabledatasource
1个回答
0
投票

新插入的对象没有永久ID。当您保存上下文时,Core Data 将为您创建一个永久 ID,或者您可以使用

obtainPermanentIDs(for: )
获取一个。但是,这可能不是解决您的问题的最佳方法。

解决您问题的最佳方法是让快照为

<String, Asset>
(或者无论是什么类型,我在您的问题中看不到)而不是
<String, NSManagedObjectID>
,那么您不需要重新获取来自数据库的内容或执行任何转换步骤。

© www.soinside.com 2019 - 2024. All rights reserved.