当从Today扩展保存到CoreData时,数据只能从Widget获得,而不能从主应用获得

时间:2022-01-06 16:01:26

I'm writing an Application for iOS with Swift 3.

我正在用Swift 3编写一个iOS应用程序。

In my Main iOS App I'm using an NSFetchedResultsController to show saved items as an TableView. It's (of course) possible to add new items from another ViewController. -> Thats all working really awesome.

在我的主要iOS应用程序中,我使用NSFetchedResultsController将保存的项目显示为TableView。(当然)可以从另一个ViewController中添加新项。->所有的工作都非常棒。

So I thought it would be great if I could add an new item really fast from an TodayWidget.

所以我想如果我能从今天的小部件中快速添加一个新项目就太好了。

What I did:

  1. Created an SharedCode Framework and added AppGroup to my Main App and the Today Widget.

    创建了一个共享代码框架,并将AppGroup添加到我的主应用程序和Today小部件中。

  2. Moved my CoreDataStack.swift Class, the .xcdatamodeled and my Item+CoreDataClass.swift and Item+CoreDataProperties.swift files to my SharedCode Framework.

    我的CoreDataStack移动。swift类,.xcdatamodeled和我的项目+CoreDataClass。斯威夫特和项+ CoreDataProperties。swift文件到我的共享代码框架。

  3. Sublcassed NSPersistentContainer to addforSecurityApplicationGroupIdentifier for my appGroupID

    下面的NSPersistentContainer到addforSecurityApplicationGroupIdentifier用于appGroupID

  4. Rewrote my CoreData code in my ViewController to use the created CoreDataStack.shared.managedContext

    在视图控制器中重写CoreData代码,以使用创建的CoreDataStack.shared.managedContext

  5. Testing. AWESOME. My NSFetchedResultsController is working, and adding new Items works as expected. Nice. -> moveing on.

    测试。太棒了。我的NSFetchedResultsController正在工作,添加新项目如预期的那样工作。好了。- >迁入。

  6. In my Today Widget I'm using an simple NSFetchRequest to get the last entered Item from CoreData. Works perfectly!

    在我的Today小部件中,我使用一个简单的NSFetchRequest从CoreData获取最后输入的项。作品完美!

  7. Added Buttons to modify the data and saving it to CoreData. Here I'm also using CoreDataStack.shared.managedContext and CoreDataStack.shared.save()

    添加按钮以修改数据并将其保存到CoreData。这里我还使用了CoreDataStack.shared。managedContext和CoreDataStack.shared.save()

  8. Automatically reloading my Data AND?! AWESOME. All working very nice. Data is saved and new data is shown in the Today Extension. Also when I count the results from my NSFetchRequest the number of Items is increased.

    自动重载我的数据?!太棒了。工作很好。数据保存,新的数据显示在今天的扩展中。当我计算NSFetchRequest的结果时,条目的数量也会增加。

NOW TO MY PROBLEM:

All the data that I'm adding through the Extension is not showing in my main iOS App. There when I'm fetching the Items from CoreData there are only the ones showing that I created in the main app. -.-

我通过扩展添加的所有数据都没有显示在我的主iOS应用中。在那里,当我从CoreData提取数据时,只有显示我在主应用中创建的数据

I have no Idea whats going wrong. It's like I have two different CoreDataStores. Also after I once added an Item trough the Widget - the Widget does not fetch an Item from the main App. Only the last one entered from the Widget.

我不知道哪里出错了。就好像我有两个不同的核心数据存储。同样,在我为小部件添加了一个项目之后——小部件不会从主应用程序中获取一个项目。

- Here is my Code:

CoreDataStack.swift

CoreDataStack.swift

public class CoreDataStack {

    public static let shared = CoreDataStack()
    public var errorHandler: (Error) -> Void = {_ in }

    //#1
    lazy var persistentContainer: PersistentContainer = {

        let container = PersistentContainer(name: ServiceConsts.modelName)
        var persistentStoreDescriptions: NSPersistentStoreDescription

        let storeUrl =  FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: ServiceConsts.appGroupID)!.appendingPathComponent("\(ServiceConsts.modelName).sqlite")

        let description = NSPersistentStoreDescription()
        description.shouldInferMappingModelAutomatically = true
        description.shouldMigrateStoreAutomatically = true
        description.url = storeUrl

        container.persistentStoreDescriptions = [NSPersistentStoreDescription(url:  FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: ServiceConsts.appGroupID)!.appendingPathComponent("\(ServiceConsts.modelName).sqlite"))]

        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container 
    }()

    //#2
    public lazy var managedContext: NSManagedObjectContext = {
        return self.persistentContainer.viewContext
    }()

    //#3
    // Optional
    public lazy var backgroundContext: NSManagedObjectContext = {
        return self.persistentContainer.newBackgroundContext()
    }()

    //#4
    public func performForegroundTask(_ block: @escaping (NSManagedObjectContext) -> Void) {
        self.managedContext.perform {
            block(self.managedContext)
        }
    }

    //#5
    public func performBackgroundTask(_ block: @escaping (NSManagedObjectContext) -> Void) {
        self.persistentContainer.performBackgroundTask(block)
    }

    //#6
    public func saveContext () {
        guard managedContext.hasChanges else { return }
        do {
            try managedContext.save()
        } catch let error as NSError {
            print("Unresolved error \(error), \(error.userInfo)")
        }
    }
}

PersistentContainer.swift

PersistentContainer.swift

class PersistentContainer: NSPersistentContainer {
    internal override class func defaultDirectoryURL() -> URL {
        var url = super.defaultDirectoryURL()
        if let newURL =
            FileManager.default.containerURL(
                forSecurityApplicationGroupIdentifier: ServiceConsts.appGroupID) {
            url = newURL
        }
        return url
    }
}

Can anyone help? I have really no idea what I'm doing wrong.

谁能帮忙吗?我真的不知道我做错了什么。

Would be so awesome if anyone can give me a tip :)

如果有人能给我一点建议那就太棒了

Thanks <3

谢谢你< 3

1 个解决方案

#1


1  

I finally fixed my issue <3.

我终于解决了我的问题<3。

It was so simple.

它是如此简单。

After hours and hours of testing testing crying and putting an axed through my MacBook ;) I found the thing thats what close killing me.

在测试了好几个小时后,我哭着把axed放到我的MacBook上;我发现了那件事,差点杀了我。

I testet if a simple Fetch Request in the Main App would get the added Items from the Today Extension. And that was working.

我测试主应用程序中的一个简单的取回请求是否会从Today扩展中获得添加的项。这是工作。

And than I saw it. In my Main App. The NSFetchedResultController. I used an cache.

比我看到的要多。在我的主应用程序中,NSFetchedResultController。我使用一个缓存。

So now I notify the Main App when a new Weight was added via the widget - and than I call my refresh function.

现在,当通过小部件添加新的权重时,我通知主应用程序——而不是调用refresh函数。

func handleRefresh(_ refreshControl: UIRefreshControl) {

    NSFetchedResultsController<NSFetchRequestResult>.deleteCache(withName: "weightCache")

    do {
        try fetchedResultsController.performFetch()
        setupView()
        self.tableView.reloadData()
    } catch let error as NSError {
        print("Fetching error: \(error), \(error.userInfo)")
    }

    refreshControl.endRefreshing()
}

So simple.

那么简单。

Just delete the cache.

只是删除缓存。

#1


1  

I finally fixed my issue <3.

我终于解决了我的问题<3。

It was so simple.

它是如此简单。

After hours and hours of testing testing crying and putting an axed through my MacBook ;) I found the thing thats what close killing me.

在测试了好几个小时后,我哭着把axed放到我的MacBook上;我发现了那件事,差点杀了我。

I testet if a simple Fetch Request in the Main App would get the added Items from the Today Extension. And that was working.

我测试主应用程序中的一个简单的取回请求是否会从Today扩展中获得添加的项。这是工作。

And than I saw it. In my Main App. The NSFetchedResultController. I used an cache.

比我看到的要多。在我的主应用程序中,NSFetchedResultController。我使用一个缓存。

So now I notify the Main App when a new Weight was added via the widget - and than I call my refresh function.

现在,当通过小部件添加新的权重时,我通知主应用程序——而不是调用refresh函数。

func handleRefresh(_ refreshControl: UIRefreshControl) {

    NSFetchedResultsController<NSFetchRequestResult>.deleteCache(withName: "weightCache")

    do {
        try fetchedResultsController.performFetch()
        setupView()
        self.tableView.reloadData()
    } catch let error as NSError {
        print("Fetching error: \(error), \(error.userInfo)")
    }

    refreshControl.endRefreshing()
}

So simple.

那么简单。

Just delete the cache.

只是删除缓存。