CoreData中FetchedResults无法初始化问题求助
问题分析与解决方案
错误的核心原因是**FetchedResults<Device>没有公开的初始化器**,你不能直接通过FetchedResults<Device>(fetchRequest: ..., managedObjectContext: ...)这种方式创建实例。FetchedResults是SwiftUI为CoreData专门设计的类型,只能通过@FetchRequest属性包装器或者底层的NSFetchedResultsController间接获取。
以下是两种适配你场景的解决办法:
方式一:在SwiftUI视图中直接使用@FetchRequest获取已保存设备
如果你的DeviceListView是SwiftUI视图,可以直接在视图内部用@FetchRequest获取CoreData中的Device实体,无需在CoreDataController中手动创建FetchedResults:
struct DeviceListView: View { // 直接通过@FetchRequest获取已保存设备 @FetchRequest(fetchRequest: Device.fetchRequest()) var savedDevices: FetchedResults<Device> // 新发现设备列表,从BLECentralManager获取 @State var discoveredDevices: [BLEDevice] = [] var body: some View { List { Section("已保存设备") { ForEach(savedDevices) { device in Text(device.name ?? "未知设备") } } Section("新发现设备") { ForEach(discoveredDevices) { device in Text(device.name) } } } } }
方式二:在CoreDataController中使用NSFetchedResultsController管理数据
如果需要在CoreDataController中封装CoreData逻辑,可以用NSFetchedResultsController来监听数据变化,并将结果发布给视图:
class CoreDataController: ObservableObject { let persistentContainer: NSPersistentContainer // 发布已保存设备列表,供视图订阅 @Published var savedDevices: [Device] = [] private var fetchedResultsController: NSFetchedResultsController<Device>? init() { persistentContainer = NSPersistentContainer(name: "YourDataModel") persistentContainer.loadPersistentStores { _, error in if let error = error { fatalError("CoreData加载失败: \(error.localizedDescription)") } self.setupFetchedResultsController() } } private func setupFetchedResultsController() { let fetchRequest: NSFetchRequest<Device> = Device.fetchRequest() // 可以添加排序规则,比如按名称排序 fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \Device.name, ascending: true)] fetchedResultsController = NSFetchedResultsController( fetchRequest: fetchRequest, managedObjectContext: persistentContainer.viewContext, sectionNameKeyPath: nil, cacheName: nil ) fetchedResultsController?.delegate = self do { try fetchedResultsController?.performFetch() savedDevices = fetchedResultsController?.fetchedObjects ?? [] } catch { print("获取设备失败: \(error.localizedDescription)") } } } // 实现NSFetchedResultsControllerDelegate,监听数据变化 extension CoreDataController: NSFetchedResultsControllerDelegate { func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { guard let devices = controller.fetchedObjects as? [Device] else { return } savedDevices = devices } }
然后在DeviceListView中使用这个控制器:
struct DeviceListView: View { @StateObject var coreDataController = CoreDataController() @State var discoveredDevices: [BLEDevice] = [] var body: some View { List { Section("已保存设备") { ForEach(coreDataController.savedDevices) { device in Text(device.name ?? "未知设备") } } Section("新发现设备") { ForEach(discoveredDevices) { device in Text(device.name) } } } } }
内容的提问来源于stack exchange,提问作者YKWIBN
相关产品推荐
相关产品推荐

