I am trying to store a plist and several binary files (let's say images) as part of an UIManagedDocument. The name of the binary files are an attribute in Core Data and I don't need to enumerate them, just access the right one when showing the related entity.
The file structure that I want to have is:
- <File yyyyMMdd-HHmmss>.extdoc
- StoreContent
- persistentStore
- AdditionalContent
- ListStatus.plist (used to store per document defaults)
- Images
- uuid1.png
- uuid2.png
- ...
- uuidn.png
So far, I have successfully followed the instructions in How do I save additional content into my UIManagedDocument file packages?, but when I try to add the binary files there are some things that I don't know how to do.
Should I treat the URL /the/path/File yyyyMMdd-HHmmss.extdoc/AdditionalContent (the default one provided with readAdditionalContentFromURL:error:) as a NSFileWrapper? Are there any advantages/disadvantages vs just using the URLs? I find it more complicated to use the file wrapper, since the plist has to be read using the file wrapper accessors and NSCoder (I guess), and the files, I have to store the file wrapper for the Images directory and then obtain the corresponding node with objectForKey (I assume). But Apple's Document-Based Apps Programming Guide for iOS regarding custom formats instead of NSData or NSFileWrapper, states "Keep in mind that your code will have to duplicate what UIDocument does for you, and so you must deal with greater complexity and a greater possibility of error." Am I misunderstanding this?
Per document defaults are declared as properties: the setter modifies the NSDictionary that maps the plist and marks the document as updated, and the getter accesses the dictionary with the proper key. How do I expose the ability to read/write the binary files? Should I add a method to my subclass of UIManagedDocument? - (void)writeImage:(NSString*)uuid; and -(UIImage *)readImage:(NSString *)uuid; And should I keep this data in memory until the document is saved? How?
Assuming that NSFileWrapper is the way to go, if I plan to use this document with iCloud should I use file coordinators with the file wrapper? If so, how?
Any source code for each question will be greatly appreciated. Thank you.
P.S.: I know that I could save some binary data inside of Core Data, but I don't feel comfortable with that solution. Among other reasons, I rather store the PNG data for image files that a serialized version of UIImage that won't be compatible with NSImage if I want to create a desktop app.
I'd like to say that, in general I rather like UIManagedDocument. It has a few advantages over raw Core Data. For example, it sets up the entire core data stack for you automatically. It also sets up nested managed object contexts for you, so you get free background saving. None of that is particularly earth-shattering, but it's a lot of functionality from a tiny amount of code.
I haven't played around with saving additional information...but here are my thoughts.
First, you shouldn't need to treat the new URL as a file wrapper. You should just be able to do regular file operations on the provided URL. Just make sure you have everything implemented properly in additionalContentForURL:error:, writeAdditionalContent:toURL:originalContentsURL:error: and readAdditionalContentFromURL:error:. The read and write operations need to be symmetric. And you should probably snapshot your data in additionalContentsForURL:error: so that everything will be saved in a known, good state (since the save operations are asynchronous).
As an alternative, have you considered using the Store in External Record File flag in your data model instead of saving it manually? This should force Core Data to (depending on the size of the binary data) automatically store them externally. I looked at the release notes, and I didn't see anything saying you couldn't use this feature with iCloud. That might be the easiest fix.
Attacking a side point for the moment (as I have not had ANY good experience with UIManagedDocument).
You can save the binary inside of Core Data for a iOS 5.0+ application using the external file reference. Then you can save the PNG of the image to Core Data directly and not need to worry about a UIManagedDocument or about bloating the sqlite file.
There is nothing stopping you from storing the PNG instead of a UIImage.
One other thought. You may need to use an NSFileCoordinator for the read and write operations. Technically, any read or write operations in the iCloud container need to use a file coordinator (to coordinate with the iCloud sync service--this prevents accidentally corrupting a file by reading it while another process is writing to it).
I know that UIDocument wraps most of its input and output methods automatically. I'd guess that these methods are similarly wrapped (since they give you a URL to use)--However, the docs aren't very clear.
Related
I am building an app which uses a TabBarController and has multiple views showing the SAME data, but in different ways. One of the views is a TableView and the other is a Map view.
The data comes from a server and I would like to have a way to store this data in which it is accessible from multiple view controllers (have a "single source of truth"). I believe that Core Data is a good choice, especially because I find the NSFetchedResultsController class rather convenient to work with when dealing with table views.
The data only needs to be around while the app is being used, so I am thinking about using Core Data without actually saving anything to the disk. I saw that there exists an In-memory store type which I believe is what I need. However, I found that just by inserting a new entity into my context (not yet calling context.save()), the NSFetchedResultsController can already detect the changes and update my UI.
Question 1:
Is it really neccessary to call context.save() when using the In-memory store type?
I believe it might be necessary in the case of multiple contexts.
Question 2:
If it is not necessary to call context.save(), does it even matter what persistent store type I use?
Any help is appreciated!
Question 1: Is it really neccessary to call context.save() when using the In-memory store type?
I believe it might be necessary in the case of multiple contexts.
That's correct. If you use the common pattern of having one context for the UI and a different one to handle incoming network data, you'll need to save changes for updates from one context to be available in the other.
Question 2: If it is not necessary to call context.save(), does it even matter what persistent store type I use?
If you use an in-memory store, your persistent store type is NSInMemoryStoreType. It matters in that choosing the right store type is how you get it to be an in-memory store.
Keep in mind that using an in-memory store means that users won't be able to use the app offline in any way. Whether that's important depends on your app, but it can be useful to let people view older data when they don't have a network connection.
I am new to J2ME development, so i am having some problems regarding storing images in RMS.
What is the diffrence between storing image in a package and storing it in RMS, is it the same thing or having any difference. Moreover, if i store image on RMS, then ultimately i would i have to keep it in package too so it consumes space at two different places.
Please help me out with this issue and assist me with the best approach to be used.
RMS is used to store data that needs to be loaded again later, like e.g. variables that is input by the user, or highscores achieved in a game.
In my opinion it would only make sense to store images in RMS, if they have been edited by the user. But even then, I'd probably go with saving them on the file-system instead.
A MIDlet cannot come with data pre-defined in RMS. In order to put data into RMS, you need to get that data from somewhere first, e.g. inside the jar file resources folder, or downloaded from the web.
I am trying to build excerpts for each document returned as a search results on my website. I am using the Sphinx search engine and the Apache web server on Linux CentOS. The function within the Sphinx API that I'd like to use is called BuildExcerpts. This function requires you to pass an array of strings where each string contains the documents contents.
I'm wondering what the best practice is for retrieving the document contents in real time as I serve the results on the web. Currently, these documents are in text files on my system, spread across multiple drives. There are roughly 100MM of them and they take up a few terabytes of space.
It's easy for me to call something like file_get_contents(), but that feels like the wrong way to do this. My databases are already gigantic ( 100GB+ ) and I don't particularly want to throw the document contents in there along with the document attributes that already exist. Perhaps this is the best way to do this, however.
Suggestions?
Well the source needs to be fetched from somewhere. If you dont want to duplicate it in your database, then you will need to fetch it from the filesystem. (using file_get_contets or similar)
Although the BuildExerpts function does give you one extra option "load_files"
... then sphinx will read the data from the filename for you.
What problem are you experiencing with reading it from files? Is it too slow? If so maybe use some caching in front - using memcache maybe.
tl;dr : Should I store directories in CouchDB as a list of attachments, or a single tar
I've been using CouchDB to store project documents. I just create documents via Futon and upload them directly from there. I've also written a script to bulk-upload directories. I am using it like a basic content repository. I replicate it, so other people on my team have a copy of the repository.
I noticed that saving directories as a series of files seems to have a lot of storage overhead, so instead I upload a .tar.gz file containing the directory. This does significantly reduce the size of the document but now any change to the directory requires replicating the entire tarball.
I am looking for thoughts or perspective on the matter.
It really depends one what you want to achieve. I will try and provide some options for you to consider.
Storing one tar.gz will save you space, but it does make it harder to work with. If you are simply archiving it may work for you.
Storing all the attachments on one document works well for couchapps. The workflow is you mess around with attachments until you are ready to release the application, then there is not a lot of overhead for replication, because it is usually one time. It is nice that they are one one document because they all move/replicate as one bundle. Downsides for using this approach for a content management system are that you can get a lot of history baggage that you have to compact on your local couch. Also you will get a lot of conflicts during replication between couches, and couch will keep conflicts around for you to resolve. Therefore if you choose this model, you should compact frequently to reduce disk size.
For a content management system, I might recommend using one document per attachment. That would give you less conflicts. There will be a slight overhead as each doc will have some space allocated for the doc itself, but the savings in having to do frequent compaction and/or conflict resolution will be better.
Hope that gives you some options to weigh out.
I am a novice in Objective-C; and I could not find any solution in my Books or internet.
My question: What are the most efficient and fastest ways to use already compiled .mom and SQLite db without having the source codes?
Details:
I am trying to connect my small app to the database of another application and use (read-inly) the part of its data. But the task is difficult since that app does not have SDK.
That app has a compiled .mom file and an SQLite database.
I succeeded to programmatically (not using IB) connect to the db using .mom and could manage to get the entities, fill data into the objects re-created by me etc.
But I am doing every step with guesses, trials and errors. Thus the development takes a lot of time and is error-prone.
The most difficult task to dissect is to-many relationships via intermediate tables.
For example: entity "Books" has a relationship to "Authors". Since the sequence of authors matters, there is an intermediate table "authorsNumbered" which contains fields: number, author, book; and the field "number" determines the exact order of authors as they should appear everywhere (important!)
I finally managed to create an ordered array of authors using NSSortDescriptor but it took me whole week to find and guess how to do it!
Would you suggest more efficient ways to deal with compiled .mom rather than the one used by me?
Thanks
If you copy the .mom file and change the extension to .plist you will get a plain text, human readable plist file which you can puzzle out with relative ease.
Create a empty model file say Example.exdatamodeld.
Select it.
In Xcode Editor -> Import and select your mom file.
You can view datamodel inside that mom file.