Swift - iOS10 - CoreData - FetchRequest в виджете Today всегда возвращает 0 элементов
Я пытаюсь использовать CoreData в своем основном приложении, и я хочу получить к нему доступ через расширение сегодня, а затем в моем приложении WatchApp.
Я добавил новую цель для своего виджета сегодня - затем активировал группы приложений для обеих целей. Конечно же, appGroup.
Затем я построил фреймворк "SharedCode". Чтобы поделиться вспомогательными классами и моим классом CoreDataStack в обоих приложениях Main и Today.
Я создал CoreDataStack, упомянутый в этом посте блога: https://swifting.io/blog/2016/09/25/25-core-data-in-ios10-nspersistentcontainer/
Также я добавил этот код, чтобы изменить каталог:
final class PersistentContainer: NSPersistentContainer {
internal override class func defaultDirectoryURL() -> URL {
var url = super.defaultDirectoryURL()
if let newURL =
FileManager.default.containerURL(
forSecurityApplicationGroupIdentifier: CoreDataServiceConsts.applicationGroupIdentifier) {
url = newURL
}
return url
}
}
Это мой класс CoreDataStack Helper:
struct CoreDataServiceConsts {
static let applicationGroupIdentifier = "nnnnnnnnn.group.is.xnd.xyz"
static let modelName = "Weight"
}
public class CoreDataStack {
public static let shared = CoreDataStack()
public var errorHandler: (Error) -> Void = {_ in }
//#1
public lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: CoreDataServiceConsts.modelName)
container.loadPersistentStores(completionHandler: { [weak self](storeDescription, error) in
if let error = error {
NSLog("CoreData error \(error), \(error._userInfo)")
self?.errorHandler(error)
}
})
return container
}()
//#2
public lazy var viewContext: 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.viewContext.perform {
block(self.viewContext)
}
}
//#5
public func performBackgroundTask(_ block: @escaping (NSManagedObjectContext) -> Void) {
self.persistentContainer.performBackgroundTask(block)
}
public func saveContext () {
guard viewContext.hasChanges else { return }
do {
try viewContext.save()
} catch let error as NSError {
print("Unresolved error \(error), \(error.userInfo)")
}
}
}
И я построил подкласс для NSPersistentContainer:
final class PersistentContainer: NSPersistentContainer {
internal override class func defaultDirectoryURL() -> URL {
var url = super.defaultDirectoryURL()
if let newURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: CoreDataServiceConsts.applicationGroupIdentifier) {
url = newURL
}
return url
}
}
В моем основном приложении я использую NSFetchedResultController - добавление и получение сущностей работает отлично:)
Теперь я хочу читать из CoreData - я использую FetchRequest:
func fetchWeights() {
let fetchRequest: NSFetchRequest<Measure> = Measure.fetchRequest()
let dateSort = NSSortDescriptor(key: #keyPath(Measure.date), ascending: false)
fetchRequest.sortDescriptors = [dateSort]
fetchRequest.returnsObjectsAsFaults = false
do {
let results = try CoreDataStack.shared.viewContext.fetch(fetchRequest)
if results.count > 0 {
// There are found Weigts
print("weights FOUND: \(results.count)")
} else {
// Nil Weights found
print("NO weights: \(results.count)")
}
} catch let error as NSError {
print("Fetch error: \(error) description: \(error.userInfo)")
}
}
Нет запроса на выборку всегда возвращает ноль объектов. Но в моем CoreData есть объекты, которые отображаются в моем основном приложении.
Есть идеи? Я понятия не имею, что я делаю не так. Спасибо за вашу помощь.
1 ответ
Вы определили PersistentContainer
подкласс переопределить defaultDirectoryURL
, но твой CoreDataStack
все еще использует сборку в NSPersistentContainer
введите для вашего ленивого контейнера.
Это должно сделать трюк:
public class CoreDataStack {
public static let shared = CoreDataStack()
public var errorHandler: (Error) -> Void = {_ in }
//#1
public lazy var persistentContainer: PersistentContainer = {
let container = PersistentContainer(name: CoreDataServiceConsts.modelName)
container.loadPersistentStores(completionHandler: { [weak self](storeDescription, error) in
if let error = error {
NSLog("CoreData error \(error), \(error._userInfo)")
self?.errorHandler(error)
}
})
return container
}()
Приветствия Михал