Core Data what is created with UIManagedDocument - objective-c

I am unsure about the structure of coreData and how the objects are saved in a directory. So what I know is that you create an instance of UIManagedDocument and make a URL for it and where it will save files. Then you call "SaveToURL", what exactly is created when you call this? is it the core data stack? Then when you save information into the entities you declared is a separate file created within the stack for each set of information in an entity? Finally, what exactly is a context of a UIManagedDocument.
These are the three main questions
What is created when you call "SaveToURL", is it a document or a
file or a stack?
When you save information in entities, are separate files created
within this file/stack?
what is a UIManagedDocument context?

I strongly suggest you read Core Data Programming Guide and start with Core Data Basics Chapter.
UIManagedDocument is a special kind of document, an UIDocument subclass, that stores its data using Core Data Framework. So it combines the power of document architecture and core data capabilities.
You can read more about document based architecture from Document Based App Programming Guide for iOS and I recommend WWDC2011 Storing Documents in iCloud using iOS5 session video. I also recommend Stanford CS193P: iPad and iPhone App Development (Fall 2011) Lecture 13.
What is created when you call saveToURL:forSaveOperation:completionHandler: is an implementation detail of UIManagedDocument and UIDocument and you should not really worry or depend on it. However in current implementation a folder containing an sqlite database file is being created.
No. All entities will be contained in a single database file also
more generally called: a persistent store. It is possible to use
more than one persistent store, but those are more advanced use
cases and UIManagedDocument currently uses one.
UIManagedDocument's context refers to a NSManagedObjectContext from underlying Core Data Framework. UIManagedDocument actually operates two of those in parallel to spin off IO operations to a background thread. When it comes to the nature of a context itself here's a quote from Core Data Programming Guide:
You can think of a managed object context as an intelligent scratch
pad. When you fetch objects from a persistent store, you bring
temporary copies onto the scratch pad where they form an object graph
(or a collection of object graphs). You can then modify those objects
however you like. Unless you actually save those changes, however, the
persistent store remains unaltered.
But it really is a good idea to take a look at the lectures and other material I posted above to get a general picture of the technologies used and their potential value to you as a developer in different situations.

Related

best place to persist an nsmutablearray of objects

I'm an OSX beginner. Where is the best place to store an NSMutableArray of objects. the objects need to be presented to the user for updating, deleting etc. I've already written the code to manage and present the data to the user. i just need to now start saving the data. i don't envisage the array containing more than 50 objects.
i'm not sure where to persist the data. should i use a os file or NSUserDefaults. what does osx etiquette say?
thanks
Since you mention that the user will need to update and delete the data, Core Data is a very good option.
In addition to the benefits of the framework itself, Core Data integrates well with the OS X tool chain. The model design tools allow you to create your schema graphically, quickly and easily. You can use templates in the Instruments application to measure Core Data’s performance, and to debug various problems. On OS X desktop, Core Data also integrates with Interface Builder to allow you to create user interfaces from your model. These aspects help to further shorten your application design, implementation, and debugging cycles.
You can read more about the key features in the documentation to be sure that's what you're looking for.

Multi User Core Data w/ XPC

Howdie,
This is my first post, so if this has been answered somewhere please forgive me (I did search).
Problem:
I have a Cocoa app that needs to share a single Core Data database among multiple user accounts on the system.
Idea:
I would create a daemon to handle requests from the users (to cross user privilege boundaries) to save/retrieve the data from Core Data. Create a shared Managed Object Context that is used in the application and pass that MOC to the daemon through NSXPCConnection. The daemon will have a fully realized Core Data Stack. I can then set the MOC that was created in the app to be a child of the MOC that was created by the daemon. Hit save and I'm done?
Question:
Would this even work? Is this just a dumb idea? What are the other solutions? NSManagedObjectContext conforms to the NSCoder protocol, but in order to use it with XPC I have to subclass it and make it conform to the NSSecureCoding protocol? Would I also just need to make sure my ManagedObject subclasses conform to NSSecureCoder protocol to use with NSXPConnection? I suppose I can ditch the context all together and just send the managed objects.
I'm assuming NSXPCConnection copys objects instead of using pointers? Is this correct?
Also, I'd probably have to keep performance in mind as the objects are coded/ decoded as fully realized objects and not faulted. Is this correct?
Thank you in advance for your help.
Maybe it works. ;-)
But there are some special problems you have to deal with. To make a long story short: I think that it would be better to use an incremental store doing this. But its documentation is close to poor.
We implemented something like this for syncing. And we have to implement this for networking. (That is, what you want to do.) Here are the problems:
A.
Moving around the context won't help. The context contains a subset of the store objects. Which one is in the context is random to the app programmer. (Inserted and changed objects will live there, but not changed, not inserted objects can be there and can go away.)
B.
You can of course move around the store. Since it is on the hard disk, this would be easier, if you have access to that location, where it is stored. You can use an XPC service for that.
Doing so has the problem that you do not know, what one user changed. You only get the whole store. In contrast an incremental store knows the specific changes through the save request.
C.
"Different users" means that you have conflicts. This is "unnatural" to Core Data. Is is a graph modeller and being that, it is not "connection based". It opens a document, owns it, changes it, stores it, and closes it. As every document it is typically not owned by two or more apps (including two running instances of one app) at one time. There is no real good mechanism for working on a store simultaneously. So you have to handle that yourself. It is probably easier to handle that on the level of the incremental store than on a level build on top of it.
What you want to do is not that easy, if you do not make assumptions you can make in your special case. (For example having a locking mechanism on a higher level.)
My 0,05 $.

Abstracting Core Data from the rest of the app (MVCS pattern)?

I'm working on an app that is basically a client for a server-side REST API.
The app relies heavily on server-data (kind of like Facebook does).
In my app I have an ServerAPI class that manages all interaction with the server. It basically acts as the "Store" in the "Model-View-Controller-Store" pattern. The rest of the app uses a singleton instance of this class to access data.
So for example if one of my view controllers needs a list of Articles, it would call:
[[ServerAPI sharedAPI] fetchArticlesWithCompletion:^(NSArray *articles){
// Do something with the new articles.
}];
This way the app doesn't care how the articles are fetched. For all it knows, they were fetched from a local file and not a server.
This is all fine and well.
The problem now is I'd like to add some sort of caching. After looking around it sounds like Core Data might be the best tool for the job (but I'm definitely open to other suggestions).
I found AFIncrementalStore (NSIncrementalStore subclass for AFNetworking) which looks promising. But from my (currently limited) understanding of NSIncrementalStore, the app (view controllers) still interact directly with NSFetchRequests and MOCs to fetch data.
I'd like to keep my current API (ServerAPI singleton) and simply plug in Core Data "behind the scenes" so that the rest of the app remains unaware of the details. Basically the app shouldn't know that data is cached, or how it is cached, it should just request data and get data.
So my question is, what's a good strategy for implementing this? Has anyone done something like this before? Is it worth the effort? I understand that Core Data is itself a way of abstracting stores, so having a second layer of abstraction might be overkill. But I keep thinking of the case where if one day I decide to use NSCoding instead of Core Data to store objects to disk. I generally don't like having all my classes know about implementation details (in this case using core data vs not using core data).
I'm a little torn on what approach is best. I don't want to invest too much time into a solution that might not make sense in the long run.
Generally does it make sense to use Core Data APIs directly in code? Or is it best to abstract away all these details behind a custom DataManager that handles both server and local data.
Thoughts?
Personally, I'd use RestKit as the bridge between the RESTful API and Core Data. I would use Core Data and I wouldn't be thinking that changing to NSCoding might be a good idea in the future (that's a really very unlikely scenario). Core Data offers you a lot of options for storage, searching and memory management. Getting the same features from another store is going to be a lot of effort or a similar level of dependency.
Either way, you have 2 options - hide the cache or don't.
If you hide it, the side effect would be that you'd really need to call the completion block twice (first for the cache hit, second for the server response). How easy that will be depends on what you're doing. The issue would be that you wouldn't be able to leverage all of the search and memory management features of your cache (like only loading pages of data from the store and loading more as the user scrolls through a list).
If you don't hide it, yes you would use fetch requests and MOCs. Probably via NSFetchedResultsController. The impact is relatively low IMHO and the benefits are large (like the automatic page management). Now your structure is - view controllers watch the 'cache' for data (the ServerAPI owns the MOC so it still mediates the store), they can get existing data immediately and if they decide new data is required they call the ServerAPI. The ServerAPI works exactly as it does now (with the completion block) and the completion block is either used as a trigger to update the UI activity indication or as the actual source of data if needs be.
As you can probably tell, I wouldn't hesitate in using Core Data and allowing its features to be used in my view controllers. The part I'm interested in shielding the rest of the code from is the server API, not the local data cache.

Why use UIDocument over standard Archiving

I have used UIDocument, but I don't understand the advantage over using Archiving? Assuming you don't want to use iCloud.
From Apple's docs: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIDocument_Class/UIDocument/UIDocument.html
Applications that make use of UIDocument and its underlying
architecture get many benefits for their documents:
Asynchronous reading and writing of data on a background queue. Your
application's responsiveness to users is thus unaffected while reading
and writing operations are taking place.
Coordinated reading and
writing of document files that is automatically integrated with cloud
services. Support for discovering conflicts between different versions
of a document (if that occurs).
Safe-saving of document data by
writing data first to a temporary file and then replacing the current
document file with it.
Automatic saving of document data at opportune
moments; this mechanism includes support for dealing with suspend
behaviors.
You get nice integration with NSUndoManager, too

Documents and Nib files: What does apple mean by "Document"?

I don't understand how the term "Document" is used in objective-C and cocoa. When I build an Application, why do I have an "Document"? That makes no sense to me. I could have an Application like an Image Editor, wherein I can open like 100 Images at same time. So every Image is a Document and has its own Nib file? Can someone explain that term in a way that's humanly understandable? Best would be a lot of examples, I think.
From my ancient but still mostly relevant Cocoa NSFAQ (Not-so FAQ):
Q18
Why would I want a Document subclass?
A18
Because you have a central data model which needs an object to manage it.
In more detail, don't always think Document==File. The conceptual Document in most Mac applications may indeed map to a single file on disk but is also often a central object (Model in classic MVC design).
If you're using a database, the Document might manage the database connection and even end up saved as a file persisting that connection.
For your photo library, the Document might be singular, just containing some settings, or you may have multiple Documents corresponding to different layouts and filters as to which photos are visible.
There's no reason why you can't have more than one Document or even hundreds open if you want to go that way - the Document is a way to provide data to views and you can have hundreds of instances if you want.
Document-based, in terms of the Xcode templates, essentially means an NSDocument subclass. NSDocument and NSDocumentController provide an abstraction that makes it simpler to support multiple documents.
You are correct, you can hand-code it without NSDocument just fine. However, NSDocument does make it a bit easier.