如何为此 SwiftUI CoreData 模型正确插入排序描述符?

Posted

技术标签:

【中文标题】如何为此 SwiftUI CoreData 模型正确插入排序描述符?【英文标题】:How do I correctly insert a sort descriptor for this SwiftUI CoreData model? 【发布时间】:2021-02-06 19:39:21 【问题描述】:

我正在尝试实现此处所述的 MVVM 架构:

https://medium.com/better-programming/swiftui-and-coredata-the-mvvm-way-ab9847cbff0f

但我在此文件中遇到运行时错误,无法确定在何处添加排序描述符:

import Foundation
import CoreData
import Combine
import UIKit

class ItemsStorage: NSObject, ObservableObject 
    var items = CurrentValueSubject<[Item], Never>([])
    private let itemFetchController: NSFetchedResultsController<Item>
    
    //SINGLETON INSTANCE
    static let shared: ItemsStorage = ItemsStorage()  ///Run time error: Thread 1: "An instance of NSFetchedResultsController requires a fetch request with sort descriptors"
    
    private override init() 
        
        /// This line doesn't solve the issue
        let sort = NSSortDescriptor(key: "name_", ascending: true)
        
        itemFetchController = NSFetchedResultsController(
        
        fetchRequest: Item.fetchRequest(),
        managedObjectContext: PersistenceController.shared.container.viewContext,
        sectionNameKeyPath: nil, cacheName: nil
        )
        
        /// This line doesn't solve the issue
        itemFetchController.fetchRequest.sortDescriptors = [sort]
        
        super.init()
        
        itemFetchController.delegate = self
        
        do 
            try itemFetchController.performFetch()
            items.value = itemFetchController.fetchedObjects ?? []
         catch 
            NSLog("Error: could not fetch objects")
        
    
    
    func add()
        
    
    
    func update(withID id: UUID) 
        
    
    
    func delete(id: UUID) 
        
    


extension ItemsStorage: NSFetchedResultsControllerDelegate  
    public func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) 
        guard let items = controller.fetchedObjects as? [Item] else  return 
        NSLog("Context has changed, reloading items ...")
        self.items.value = items
    

【问题讨论】:

【参考方案1】:

在初始化获取结果控制器之前,您需要为 fetchRequest 设置排序描述符:

    let sort = NSSortDescriptor(key: "name_", ascending: true)
    let itemFetchRequest = Item.fetchRequest()
    itemFetchRequest.sortDescriptors = [sort]
    
    itemFetchController = NSFetchedResultsController(
    
    fetchRequest: itemFetchRequest,
    managedObjectContext: PersistenceController.shared.container.viewContext,
    sectionNameKeyPath: nil, cacheName: nil
    )

【讨论】:

谢谢。但是,我在“let itemFetchRequest = Item.fetchRequest()”这行出现错误。它说“模糊使用 'fetchRequest()'” 但在我的 Item+Helper.swift 文件中,我确实有定义 fetchRequest 的扩展名,如下所示:extension Item static func fetchRequest(_ predicate: NSPredicate) -&gt; NSFetchRequest&lt;Item&gt; let request = NSFetchRequest&lt;Item&gt;(entityName: "Item") return request 我的问题还有什么? 好的,多看了一下,发现这个:***.com/questions/56838434/… 这似乎解决了后一个问题。现在我有了这个:let sort = NSSortDescriptor(key: "name_", ascending: true) let itemFetchRequest: NSFetchRequest&lt;Item&gt; = Item.fetchRequest() itemFetchRequest.sortDescriptors = [sort] itemFetchController = NSFetchedResultsController ( ...

以上是关于如何为此 SwiftUI CoreData 模型正确插入排序描述符?的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 中的 CoreData:如何清楚地获取属性?

SwiftUI:按核心数据属性分组和求和

SwiftUI 使用 CoreData 从列表中编辑项目

如何在 SwiftUI 的 PreviewProvider 中编写示例模型对象?

如何通过在同一 CoreData 模型中提供 id(UUID) 来获取数据?

Swiftui中CoreData关系和显示图像列表