我无法从 widgetKit 扩展上的应用程序中检索 xcdatamodeld 数据

Posted

技术标签:

【中文标题】我无法从 widgetKit 扩展上的应用程序中检索 xcdatamodeld 数据【英文标题】:I can't retrieve the xcdatamodeld data from the app on the widgetKit extension 【发布时间】:2021-01-08 14:58:21 【问题描述】:

您好,我无法在 widgetKit 扩展上从我的应用中检索 xcdatamodeld 数据。 然而,我为两者都添加了 appGroup。检查我的模型和两者的 xcdatamodeld 文件。

我的班级核心数据:

public class CoreDataStackT4U 
    static let shared = CoreDataStackT4U()

    private init() 

    lazy var persistentContainer: NSPersistentContainer = 
        let container = NSPersistentContainer(name: "ios")
        let storeURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.fr.app")!.appendingPathComponent("ios.sqlite")

        var defaultURL: URL?
        if let storeDescription = container.persistentStoreDescriptions.first, let url = storeDescription.url 
            defaultURL = FileManager.default.fileExists(atPath: url.path) ? url : nil
        

        if defaultURL == nil 
            container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: storeURL)]
        
            container.loadPersistentStores(completionHandler:  storeDescription, error in
                       if let error = error as NSError? 
                           print(error.localizedDescription)
                       
                   )
                   return container
               ()


// MARK: - Main context
extension CoreDataStackT4U 
    var managedObjectContext: NSManagedObjectContext 
        persistentContainer.viewContext
    

    func saveContext() 
        managedObjectContext.performAndWait 
            if managedObjectContext.hasChanges 
                do 
                    try managedObjectContext.save()
                 catch 
                    print(error.localizedDescription)
                
            
        
    
 

还有我的班级小部件:

import WidgetKit
import SwiftUI
import Intents

struct Provider: IntentTimelineProvider 
    func placeholder(in context: Context) -> SimpleEntry 
        SimpleEntry(date: Date(), configuration: ConfigurationIntent())
    

    func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) 
        let entry = SimpleEntry(date: Date(), configuration: configuration)
        completion(entry)
    

    func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) 
        var entries: [SimpleEntry] = []

        // Generate a timeline consisting of five entries an hour apart, starting from the current date.
        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)
            entries.append(entry)
        

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


struct SimpleEntry: TimelineEntry 
    let date: Date
    let configuration: ConfigurationIntent


struct t4uWidgetEntryView : View 
    var entry: Provider.Entry
    var moc = CoreDataStackT4U.shared.managedObjectContext
       @FetchRequest(entity: Vehicle.entity(), sortDescriptors: [
              NSSortDescriptor(keyPath: \Vehicle.name, ascending: true)
          ]) var vehicles: FetchedResults<Vehicle>

    var body: some View 
            VStack(alignment: .leading)
                   Spacer()
                   Text("White Tiger")
                    .font(.body)
                       .bold()
                       .padding(.bottom, 20)
                       .padding(.leading, 20)
                       .padding(.trailing, 20)
                       .minimumScaleFactor(0.5)
                       .foregroundColor(.white)
                       .shadow(
                           color: Color.black,
                           radius: 1.0,
                           x: CGFloat(4),
                           y: CGFloat(4))
                Spacer()
                Text("Items count: \(vehicles.count)")
                                        
                        .foregroundColor(.white)
                        .shadow(
                            color: Color.black,
                            radius: 1.0,
                            x: CGFloat(4),
                            y: CGFloat(4))
                
               
               .frame(maxWidth: .infinity, maxHeight: .infinity)
               .edgesIgnoringSafeArea(.all)
               .background(
                Color.blue.opacity(0.8))
           
    


@main
struct t4uWidget: Widget 
    let kind: String = "t4uWidget"
    let moc = CoreDataStackT4U.shared.managedObjectContext
    var body: some WidgetConfiguration 
        IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider())  entry in
            t4uWidgetEntryView(entry: entry)
         .environment(\.managedObjectContext, self.moc)
        
        .configurationDisplayName("My t4u widget")
        .description("This is t4u widget.")
    


struct t4uWidget_Previews: PreviewProvider 
    static var previews: some View 
        t4uWidgetEntryView(entry: SimpleEntry(date: Date(), configuration: ConfigurationIntent()))
            .previewContext(WidgetPreviewContext(family: .systemSmall))
    


对车辆的请求始终为 0。 感谢您的帮助,举个例子会很有用,因为我没有看到错误。

【问题讨论】:

@FetchRequest 不能在小部件中使用。见Fetch data from CoreData for iOS 14 widget 【参考方案1】:

我忘了补充:

let storeURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.fr.app")!.appendingPathComponent("ios.sqlite")

在 AppDelegate 到我的 APP 谢谢。

【讨论】:

以上是关于我无法从 widgetKit 扩展上的应用程序中检索 xcdatamodeld 数据的主要内容,如果未能解决你的问题,请参考以下文章

从主应用程序目标 SwiftUI 访问 WidgetKit IntentTimelineProvider

仅限于 WidgetKit 时间线条目?

在 WidgetKit 的应用程序组上存储一个数组

如果正在使用我的小部件,如何查询 WidgetKit?

WidgetKit - 与文本和图像的链接

WidgetKit 未更新