Я пытаюсь сделать сегодняшнее расширение для моего ios приложения. Это расширение сегодня будет отображать «следующий» курс на основе данных, сохраненных с основными данными. Я провел некоторое исследование и понимаю, что должен поделиться своим persistentContainer с группой приложений. Итак, я сделал:
- включил группы приложений как для ios приложений, так и для сегодняшних целей расширения.
- закодировал функцию, чтобы поделиться ей:
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")
}
}
Я также пытался создать запрос на выборку, но в результате я получил пустой массив. Почему я не получаю никакого результата?
Еще одна вещь: я использовал контроллер nsfetchedResult, чтобы обновлять sh данные просмотра каждый раз, когда данные обновляются из приложения ios, так что это нормально, или я должен использовать метод widgetPerformUpdate? В этом случае мы не знаем, когда будет обновлено сегодняшнее расширение, и оно может отображать устаревшие данные.
Основная используемая документация: https://www.avanderlee.com/swift/core-data-app-extension-data-sharing/