3

我有使用 Swift 编写的 iOS 应用程序,可与 Core Data 一起使用。不,我想获取 Core Data 中存在的最后一条记录并将其呈现在 Today Widget Extension 中。

  1. 我在我的项目中添加了新的小部件目标
  2. 在我的coredata.xcdatamodeld中,我还检查了扩展的目标成员资格
  3. 对于两个目标(应用程序和扩展程序),我添加并启用了专门创建的应用程序组group.myapp.sharingForTodayExtension
  4. 这是我来自 TodayViewController 的代码

    import UIKit
    import NotificationCenter
    import CoreData
    
    class TodayViewController: UIViewController, NCWidgetProviding {
    
            var managedObjectContext : NSManagedObjectContext?
    
            override func viewDidLoad() {
                    super.viewDidLoad()
    
           let container = PersistentContainer(name: "containerName")
           container.loadPersistentStores { (storeDesc, error) in
           if let error = error {
            print("Widget Core Data loading error.... \(error)")
            return
           }
    
        print("loaded fine")
        self.managedObjectContext = container.viewContext
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "appEntities")
    
        if let fetchResults = (try? self.managedObjectContext?.fetch(fetchRequest)) as? [myCoreDataObjectType] {
            print("records count = \(fetchResults.count)")
        }
    

这是 PersistentContainer 的特殊类

class PersistentContainer: NSPersistentContainer{
     override class func defaultDirectoryURL() -> URL{
    return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.myapp.sharingForTodayExtension")!
}

override init(name: String, managedObjectModel model: NSManagedObjectModel) {
    super.init(name: name, managedObjectModel: model)
}}

问题是它显示记录数 = 0

4

1 回答 1

1

当您更改返回的值时,defaultDirectoryURL您更改了持久存储文件的位置。您的应用在此更改之前已经拥有的任何数据都应该仍然存在,但在旧位置。

如果您需要保留对现有数据的访问权限,并且该数据对应用程序和扩展程序都可用,则需要将旧数据移动到新的共享位置。

您可以通过几种方式做到这一点。

  • 用于NSPersistentStoreCoordinator在应用程序中加载旧数据,然后使用其migratePersistentStore(_:to:options:withType:)方法将数据移动到新的持久存储。
  • 用于FileManager移动文件。除了主持久存储文件之外,请确保获取两个日志文件。如果您有允许外部存储的二进制属性,这可能会很棘手。
  • 创建两个NSPersistentContainer实例,一个用于旧位置,一个用于新位置,然后编写您自己的代码以从其中一个读取对象并在另一个中创建副本。
于 2017-12-21T20:25:51.783 回答