我正在尝试为我的iOS应用制作一个今日扩展。 该扩展将显示基于使用核心数据保存的数据的“下一个”课程。 我已经做了一些研究,我明白我必须与应用组共享我的persistentContainer。 因此,我做了以下操作:
- 为iOS应用和今日扩展目标启用了appGroups。
- 编写了一个函数来共享它:
public extension NSPersistentContainer {
func addToAppGroup(id: String) {
guard let fileContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: id) else {
fatalError("Shared file container could not be created.")
}
let storeURL = fileContainer.appendingPathComponent("\(self.name).sqlite")
let storeDescription = NSPersistentStoreDescription(url: storeURL)
self.persistentStoreDescriptions.append(storeDescription)
}
}
然后在我的核心数据堆栈中:
internal class CoreDataContainer {
static var persistentContainer: NSPersistentContainer = {
let container = NSPersistentCloudKitContainer(name: "SchoolCompanion")
container.addToAppGroup(id: "group.com.Ce-dricLoneux.School-Companion")
container.loadPersistentStores(completionHandler: { (_, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext () {
let context = CoreDataContainer.persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}
文件和xcdatamodel在两个目标之间共享。此时我认为我可以从我的扩展中访问核心数据,但是当我进行获取请求时,我没有得到任何结果。controllerDidChangeContent永远不会执行。
class TodayViewController: UIViewController, NCWidgetProviding {
private func configureFetchedResultsController() {
let request: NSFetchRequest<Course> = Course.fetchRequest()
request.sortDescriptors = []
self.fetchedResultsController = NSFetchedResultsController<Course>(fetchRequest: request, managedObjectContext: CoreDataContainer.persistentContainer.viewContext, sectionNameKeyPath: nil, cacheName: nil)
self.fetchedResultsController.delegate = self
do {
try self.fetchedResultsController.performFetch()
} catch {
print(error.localizedDescription)
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.extensionContext?.widgetLargestAvailableDisplayMode = .compact
self.configureFetchedResultsController()
}
func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) {
// Perform any setup necessary in order to update the view.
// If an error is encountered, use NCUpdateResult.Failed
// If there's no update required, use NCUpdateResult.NoData
// If there's an update, use NCUpdateResult.NewData
completionHandler(NCUpdateResult.newData)
}
}
// MARK: - FetchedResultsController Delegate
extension TodayViewController: NSFetchedResultsControllerDelegate {
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
print("content did change")
}
}
我尝试直接进行fetch请求,但是结果返回一个空数组。为什么没有得到任何结果?
另外一件事:我使用了nsfetchedResult控制器来刷新视图数据,每次从ios应用程序更新数据时都会自动更新视图数据。这样做可以吗?还是应该使用widgetPerformUpdate方法?在那种情况下,我们不知道今天的扩展将何时被刷新,它可能显示过时的数据。
主要文档使用:https://www.avanderlee.com/swift/core-data-app-extension-data-sharing/