Swift 如何存储基于文档的设置?

Swift 如何存储基于文档的设置?,swift,macos,core-data,Swift,Macos,Core Data,我有一个核心数据、基于文档、脚本支持的OSX项目。每个文档都有一个特定的日历年和所在的省/州,因此我创建了一个设置实体,在创建文档时要求提供这些值。由于某些行为基于这些设置,因此其他自定义NSManagedObject类需要请求它们,而且每次需要该值时执行NSFetchRequest似乎并不正确。但是,我不确定在核心数据之外将值复制到哪里 AppDelegate——据我所知,每个应用程序只有一个,而不是每个文档,所以这并不合适 文档-这似乎是最好的,但我不确定以后如何从NSManagedObje

我有一个核心数据、基于文档、脚本支持的OSX项目。每个文档都有一个特定的日历年和所在的省/州,因此我创建了一个设置实体,在创建文档时要求提供这些值。由于某些行为基于这些设置,因此其他自定义NSManagedObject类需要请求它们,而且每次需要该值时执行NSFetchRequest似乎并不正确。但是,我不确定在核心数据之外将值复制到哪里

  • AppDelegate——据我所知,每个应用程序只有一个,而不是每个文档,所以这并不合适

  • 文档-这似乎是最好的,但我不确定以后如何从NSManagedObject中再次找到该文档。我尝试在文档中定义一个var year,然后从NSManagedObject调用window.controller?.Document?.year,但是如果我不自己设置它,则窗口为零。此外,窗口是全局的,在AppDelegate之外,所以即使我定义了它(在文档的makeWindowController()中由window=windowController.window定义),它也会变为每个应用程序,所以每次调用这一行,我都会查找上一个打开的文档(最后一个覆盖窗口的文档)的年份,而不是活动文档。我不确定如何找到对当前窗口的引用

  • 用户默认值-同样,这是每个应用程序,而不是每个文档。我当前的解决方案使用这些默认值,然后在每次调用windowDidBecomeMain时重新定义默认值(使用NSFetchRequest),因此当前文档将用户默认值设置为自己的设置


  • 似乎我不是唯一一个想要每个文档设置的人,但我似乎找不到任何示例或以前关于如何/在何处定义这些设置的问题。非常感谢您的帮助

    您正在描述每个文档的元数据,幸运的是核心数据支持这种元数据。每个持久存储文件(即
    NSPersistentDocument
    使用的文件)都可以有自己的元数据字典,其中包含您需要的任何键和值。它有点像用户默认值,只是它是文档的一部分。此数据是文件的一部分,但与构成实际文档数据的SQLite存储区分开

    元数据API位于
    NSPersistentStoreCoordinator
    上。您可以通过
    self.managedObjectContext.persistentStoreCoordinator
    在文档中获取协调员。有几种方法可以读取和写入文档元数据。在元数据中保存您的年份和省/州,然后在打开文档时查找并查阅


    核心数据有自己的元数据,您不希望丢失这些元数据——因此,在编辑元数据时,请确保查找现有元数据,对其进行修改并保存新数据。不要只为文档分配一个全新的元数据字典。

    你真漂亮!真不敢相信我以前读过的任何关于核心数据的阅读资料都没有得出这个结论。无法确定如何将以前的实体迁移到元数据中,因此在第一次运行更新时向用户发出警告以更新这两个值就足够了。否则它看起来会工作得很好。给其他人的提示:在
    .setMetadata(:forPersistentStore:)
    之后,不要忘记
    managedObjectContext.save()
    ,否则它将不起作用。更正:
    managedObjectContext.save()
    将提示用户文档已被其他应用程序更改,并提供“无论如何保存”或“还原”选项。调用
    saveDocument(nil)
    让文档保存存储似乎更安全,或者更好的做法是,调用
    updateChangeCount(.ChangeDone)
    让autosave在准备好后为您完成工作。