Access Core App Data from IOS widget

Hello,
I am working on IOS 14 widget. I want to display core data on the widget, but unable to access the data.

How can i access the core app data from within the widget.

Replies

I faced the same issue. I was able to solve it by modifying my NSPersistantContainer as follows:

Code Block swift
let container: NSPersistentContainer = {
let pc = NSPersistentContainer(name: "Model")
let storeURL = URL.storeURL(for: "group.hourglass", databaseName: "group.hourglass")
let storeDescription = NSPersistentStoreDescription(url: storeURL)
pc.persistentStoreDescriptions = [storeDescription]
pc.loadPersistentStores { _, error in
if let error = error {
fatalError(error.localizedDescription)
}
}
    return pc
}()


using this extension on URL:

Code Block swift
public extension URL {
    static func storeURL(for appGroup: String, databaseName: String) -> URL {
        guard let fileContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup) else {
            fatalError("Shared file container could not be created.")
        }
        return fileContainer.appendingPathComponent("\(databaseName).sqlite")
    }
}


where group.hourglass is the name of my shared App Group between my App and Widget targets.

Source: SwiftLee article: "Core Data and App extensions: Sharing a single database"

rr0924's answer doesn't work for me, still always returns 0 objects...
I wanted to give this thread a bump because I too am facing the same issue. The proposed answer from rr0924, and the referenced article from Antoine van der Lee, does not work for me either.

To inject my CoreData model into the Widget extension one failing attempt I've tried was to use a similar method in my iOS app and watchOS companion app. For example this code will allow proper access to CoreData from iOS and watchOS;

Code Block
@main
struct RunRosterApp: App {
@Environment(\.scenePhase) private var scenePhase
@StateObject private var persistentStore = PersistentStore.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistentStore.context)
}
}


The PersistentStore class is a set up as a singleton to load the NSPersistentCloudKitContainer. That code is fairly boiler plate so I won't post it but can upon request.

Using a similar pattern in WidgetKit and SwiftUI I currently have this;

Code Block
@main
struct WidgetRunPlanner: Widget {
@StateObject private var persistentStore = PersistentStore.shared
private let kind: String = "WidgetRunPlanner"
public var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
WidgetRunPlannerEntryView(entry: entry)
.environment(\.managedObjectContext, persistentStore.context)
}
}


Unfortunately this is not right and the Widget will crash at the first attempt of a CoreData fetch request with the following error:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+entityForName: nil is not a legal NSPersistentStoreCoordinator for searching for entity name 'RunEvents''

If you have any experience with this any help is greatly appreciated. The Target Membership checkbox's have been appropriately checked.

Thank you,
Dan


Hey guys,
My main app is in Objective-c, and i was able to get the data to show up on widget.

Main thing to note is : Widget will NOT have any access to App data. I followed a tutorial to access data.

For some reason apple doesn't let me include the link to the tutorial i followed. Search for this text on google " atomic bird ios widget" and chose the second link with heading " Sharing data between iOS apps and app extensions", this guy explained it really well.

Feel free to reach out to me at parimi816@gmail.com, i have had a tough time figuring it out, and would be more than happy to help anyone who is facing issues.
Does anyone know how to move a database assuming you have a production core data app with the default URL? and you want to start using a widget?
"My main app is in Objective-c, and i was able to get the data to show up on widget. I followed a tutorial to access data."

How did you do that? Can you link the tutorial please ?
@ yanfromvancouver 
hi , how can use it in widget?? give me a sample for query!?

Problem:

Since app extensions run as part of a host application rather than as part of their containing app (i.e. your app’s extensions run in somebody else’s app), data sharing isn’t automatic.

Solution:

The preferred way is to track changes (History Tracking) in the app's entities and update into widget's entities.  Refer: https://developer.apple.com/documentation/coredata/consuming_relevant_store_changes

Approach:

1.0 - Create App Groups

2.1 - Create separete app entities and widget entities

2.2 - Create separate configurations for app entities and widget entities  

2.3 - Assign them configuration to their entities

3.0 - Use app group while creating and loading the container

4.0 - Use history tracking to track changes from the app's entities and update into widget's entites.