Using NSPersistentDocument to create 'Documents'

烂漫一生 提交于 2019-12-03 21:43:28

问题


I would like to create an app that uses

  • Swift
  • CoreData
  • 'Documents' which work in the standard macOS fashion [custom extension, a single 'file'/filewrapper containing all data relating to that document]

This does not appear possible. The documentation states very clearly that

NSPersistentDocument does not support some document behaviors: File wrappers. [..]

which makes me think that the usual ways of dealing with images in CoreData - binary data with 'allow external storage' and save them to a different location, store the URL in the database - cannot be used with NSPersistentDocument. I want my users to be able to do the usual Finder operations on my 'file' (duplicate, move to external storage, restore from external backup) and need all my data to be in one single package.

The SQL version of the file store results in the usual three-fold stack when saving - .sqlite, .sqlite-shm, .sqlite-wal - which is useless as a 'document'.

Is there a solution I have overlooked? (examples are very sparse; the Big Nerd Ranch sample does not solve this, either; neither Marcus Zarra nor Objc.io touch on NSPersistentDocument).


回答1:


The only option that will work with NSPersistentDocument the way you want it is to store the images directly in the database. You need a Binary Data attribute on your entity, but you cannot turn on the Allows External Storage option.

If you turn on this option, Core Data will decide - depending on the size - whether to store the image directly in the database or in a hidden folder inside the folder where your document is located:

(I made the folder visible entering cmd-shift-. in the Finder). The sample document is named Test 1.doof and it contains three images:

You can see that the hidden folder .Test 1_SUPPORT/EXTERNAL DATA contains two files, which are the two bigger images (1.3 MB and 494 KB). The third one with only 50 KB is stored inside Test 1.doof. If you move Test 1.doof into another folder, the hidden folder is left behind. Opening the file in that other folder leads to two missing images.

Storing the images inside the database is not that bad if you put the binary data into a separate entity with a one-to-one relation to the rest of the data, like so:

That way the image does not interfere with any search or sort operation. NSPersistentDocument gives you a lot of cool functionality for free, so you should use it anyway if possible.

Two additional remarks:

  • If you turn on Allows External Storage for an attribute, you do not have to care about URLs or where to store the images, Core Data does that for you (but not in a useful way for document-based apps).
  • These shm or wal files are temporary files that appear "sometimes", for databases without external storage as well. If they stick, you can safely remove them when you app is closed.



回答2:


If you want to put more then just a database in your document, then you should implement NSDocument instead of NSPersistentDocument. In that case you don't get built-in support for CoreData, but you can use your document as a container for multiple file types.

See also Is NSDocument and CoreData a possible combination, or is NSPersistentDocument the only way?



来源:https://stackoverflow.com/questions/45356025/using-nspersistentdocument-to-create-documents

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!