简体   繁体   English

Swift - iOS10 - CoreData - Today 小部件中的 FetchRequest 总是返回 0 个元素

[英]Swift - iOS10 - CoreData - FetchRequest in Today Widget always return 0 elements

I try to use CoreData in my Main Application and I want to access it via an Today Extension and later in my WatchApp.我尝试在我的主应用程序中使用 CoreData,并且我想通过 Today Extension 以及稍后在我的 WatchApp 中访问它。

I added a new target for my Today Widget - than activated AppGroups for both targets.我为我的 Today Widget 添加了一个新目标 - 而不是为两个目标激活 AppGroups。 Of course the same appGroup.当然是同一个appGroup。

Then I builded an "SharedCode" Framework.然后我构建了一个“SharedCode”框架。 To share helper classes and my CoreDataStack class in both, my Main and Today application.在我的 Main 和 Today 应用程序中共享助手类和我的 CoreDataStack 类。

I builded the CoreDataStack mentioned in this Blogpost: https://swifting.io/blog/2016/09/25/25-core-data-in-ios10-nspersistentcontainer/我构建了这篇博客文章中提到的 CoreDataStack: https ://swifting.io/blog/2016/09/25/25-core-data-in-ios10-nspersistentcontainer/

Also I added this code tho change the directory:我还添加了此代码来更改目录:

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

This is my CoreDataStack Helper class:这是我的 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)")
        }
    }
}

And I builded a subclass for NSPersistentContainer:我为 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
    }
}

In my Main Application I use NSFetchedResultController - adding and getting Entitys is working perfectly fine :)在我的主应用程序中,我使用 NSFetchedResultController - 添加和获取实体工作得很好:)

Now I want to read from CoreData - I use a FetchRequest:现在我想从 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)")
    }
}

No the fetch request always return zero objects.否,获取请求始终返回零个对象。 But there are entities in my CoreData - there are showing in my Main App.但是我的 CoreData 中有实体 - 在我的主应用程序中有显示。

Any ideas?有任何想法吗? I have no idea what Im doing wrong.. Thanks for your help.我不知道我做错了什么..谢谢你的帮助。

You have defined a PersistentContainer subclass to override defaultDirectoryURL , but your CoreDataStack is still using the build in NSPersistentContainer type for your lazy container.您已经定义了一个PersistentContainer子类来覆盖defaultDirectoryURL ,但是您的CoreDataStack仍然使用NSPersistentContainer类型中的构建作为您的惰性容器。

This should do the trick:这应该可以解决问题:

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

Cheers Michał干杯米哈乌

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM