2

我正在使用 Swift 3 为 iOS 编写应用程序。

在我的主要 iOS 应用程序中,我使用 NSFetchedResultsController 将保存的项目显示为 TableView。(当然)可以从另一个 ViewController 添加新项目。-> 这一切真的很棒。

所以我想如果我能从 TodayWidget 中快速添加一个新项目会很棒。

我做了什么:

  1. 创建了一个 SharedCode 框架并将 AppGroup 添加到我的主应用程序和今日小部件中。

  2. 将我的CoreDataStack.swift类、.xcdatamodeled和我的Item+CoreDataClass.swiftItem+CoreDataProperties.swift文件移动到我的 SharedCode 框架中。

  3. 子类化 NSPersistentContainer 为我的 appGroupID添加用于SecurityApplicationGroupIdentifier

  4. 在我的 ViewController 中重写了我的 CoreData 代码以使用创建的CoreDataStack.shared.managedContext

  5. 测试。惊人的。我的 NSFetchedResultsController 正在工作,并且添加新项目按预期工作。好的。-> 继续前进。

  6. 在我的 Today Widget 中,我使用一个简单的 NSFetchRequest 从 CoreData 获取最后输入的项目。完美运行!

  7. 添加了用于修改数据并将其保存到 CoreData 的按钮。这里我也使用CoreDataStack.shared.managedContextCoreDataStack.shared.save()

  8. 自动重新加载我的数据和?!惊人的。一切都很好。数据已保存,新数据显示在 Today Extension 中。此外,当我计算 NSFetchRequest 的结果时,项目的数量也会增加。

现在我的问题:

我通过扩展添加的所有数据都没有显示在我的主 iOS 应用程序中。当我从 CoreData 获取项目时,只有那些显示我在主应用程序中创建的项目。-.-

我不知道出了什么问题。就像我有两个不同的 CoreDataStores。同样在我通过小部件添加项目之后 - 小部件不会从主应用程序中获取项目。只有从小部件输入的最后一个。

- 这是我的代码:

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

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
    }
}

任何人都可以帮忙吗?我真的不知道我做错了什么。

如果有人能给我小费,那就太棒了:)

谢谢 <3

4

1 回答 1

1

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

就这么简单。

经过数小时的测试,测试哭泣并通过我的 MacBook 被砍掉了;)我发现了那件事,那就是接近杀死我的东西。

我测试主应用程序中的简单获取请求是否会从今日扩展中获取添加的项目。那是有效的。

而不是我看到的。在我的主应用程序中。NSFetchedResultController。我使用了缓存

所以现在我在通过小部件添加新权重时通知主应用程序 - 然后我调用我的刷新函数。

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()
}

很简单。

只删除缓存。

于 2017-01-31T21:35:12.347 回答