You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Widget中读取CoreData?调用fetch时报TimelineProviderContext无对应成员错误

错误原因

你代码里调用fetch方法的context是getTimeline方法传入的TimelineProviderContext类型参数,属于Widget时间线提供者的上下文对象,不是CoreData用来执行查询的NSManagedObjectContext实例,自然不存在fetch方法。

修复步骤

  • 把执行查询的对象替换为你已经声明好的CoreData上下文moc,也就是你之前定义的CoreDataStack.shared.managedObjectContext
  • loadPersistentStores是异步执行的,你原本的代码在容器还没加载完存储的时候就执行查询,会拿不到数据,需要把查询逻辑放到loadPersistentStores的回调闭包里
  • 你原来的代码调用了两次completion,一次是拿到查询结果就调用,一次是最后生成默认时间线再调用,会导致逻辑异常,需要把时间线生成的逻辑也放到查询完成的流程里,把查询到的数据传给SimpleEntry

修复后参考代码

func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
    let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: <替换为你的GroupID>)!
    let storeURL = containerURL.appendingPathComponent("DataModel.sqlite")
    let description = NSPersistentStoreDescription(url: storeURL)

    let container = NSPersistentContainer(name: "Entity")
    container.persistentStoreDescriptions = [description]
    container.loadPersistentStores { description, error in
        if let error = error {
            fatalError("Unable to load persistent stores: \(error)")
        }
        // 存储加载完成后再执行查询
        let moc = CoreDataStack.shared.managedObjectContext
        let request = NSFetchRequest<Entity>(entityName: "Entity")
        request.predicate = NSPredicate(format: "attribute1 == %@", "test")
        
        var yourResult : [Entity]?
        do {
            // 这里换成moc调用fetch,不是传入的Widget context
            yourResult = try moc.fetch(request)
        } catch let error as NSError{
            print(error.localizedDescription)
        }
        
        // 生成带查询结果的时间线,需要你先给SimpleEntry加个存储CoreData结果的属性,示例名为dataList
        var entries: [SimpleEntry] = []
        let currentDate = Date()
        for hourOffset in 0 ..< 5 {
            let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
            let entry = SimpleEntry(date: entryDate, configuration: configuration, dataList: yourResult ?? [])
            entries.append(entry)
        }

        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }
}

额外注意事项

  • 确认你的CoreDataStack已经配置了共享App Group的存储路径,和你上面创建的NSPersistentContainer指向同一个存储文件,避免主App和Widget读取的不是同一个数据库
  • 确认Widget的Target已经勾选了App Group能力,和主App使用同一个Group ID

内容的提问来源于stack exchange,提问作者71873

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 13:12:03