Load data from Core Data to Today Widget

856 views Asked by At

I have iOS app written in Swift that works with Core Data. No I want to get last record that exists in Core Data and present it in Today Widget Extension.

  1. I added new widget target to my project
  2. In my coredata.xcdatamodeld I also checked target membership for extension
  3. For both targets (app and extension) I added and enabled specially created App Group group.myapp.sharingForTodayExtension
  4. Here is my code from TodayViewController

    import UIKit
    import NotificationCenter
    import CoreData
    
    class TodayViewController: UIViewController, NCWidgetProviding {
    
            var managedObjectContext : NSManagedObjectContext?
    
            override func viewDidLoad() {
                    super.viewDidLoad()
    
           let container = PersistentContainer(name: "containerName")
           container.loadPersistentStores { (storeDesc, error) in
           if let error = error {
            print("Widget Core Data loading error.... \(error)")
            return
           }
    
        print("loaded fine")
        self.managedObjectContext = container.viewContext
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "appEntities")
    
        if let fetchResults = (try? self.managedObjectContext?.fetch(fetchRequest)) as? [myCoreDataObjectType] {
            print("records count = \(fetchResults.count)")
        }
    

And here is special class for PersistentContainer

class PersistentContainer: NSPersistentContainer{
     override class func defaultDirectoryURL() -> URL{
    return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.myapp.sharingForTodayExtension")!
}

override init(name: String, managedObjectModel model: NSManagedObjectModel) {
    super.init(name: name, managedObjectModel: model)
}}

The problem is it shows that records count = 0

1

There are 1 answers

1
Tom Harrington On

When you changed the value returned by defaultDirectoryURL you change the location of the persistent store file. Any data that your app already has before this change should still be present, but in the old location.

If you need to keep access to existing data and have that data available to both the app and the extension, you'll need to move the old data to the new shared location.

You can do this in a few ways.

  • Use NSPersistentStoreCoordinator to load the old data in the app and then use its migratePersistentStore(_:to:options:withType:) method to move data to the new persistent store.
  • Use FileManager to move the files over. Make sure to get both of the journal files in addition to the main persistent store file. If you have binary properties where external storage is allowed, this may be tricky.
  • Create two NSPersistentContainer instances, one for the old location and one for the new, and write your own code to read objects from one and create duplicates in the other.