Ok, let's say I'm making a bird watch app.
There's an "official" birds database. Which is stored in one UIManagedDocument
. It's used to populate UITableView
with all the birds and a little detailed view for each of them with pictures and data. This database will be upgraded in the future with more bird species.
Then the user can go out to the countryside and take pictures of birds. He adds them to another section of the app, called the "diary" and when he identifies the bird he then links it with one "official" bird. This information (all user collected data) should be backed up with iCloud. And it's also used to populate the diary's UITableView
and detailed views.
From a diary's detailed view you can go to the "official" bird's detailed view. And from that view you can go to a list with all the registers of that bird in the user's diary.
The question is: Should I use one UIManagedDocument
for each one of the user's entries? How does that work with a UITableView
with thumbnails?
A
UIDocument
is a management class for physical File Wrappers. AUIManagedDocument
is a subclass of that which provides a CoreData stack.A File Wrapper is not much more than an abstraction for a folder or file. For
UIManagedDocument
that folder contains a SQLite database which the CoreData stack connects to.You wouldn't use individual Documents for Diary entries any more than you would use an individual Word document for each paragraph of writing.
Since your app sounds more like what Apple calls a "Shoebox app" in which one user has a single pile of data which they add to and subtract from theres no real need to use the Document Architecture. However in saying this
UIManagedDocument
provides you with a free stack so may prove useful.If it was me constructing this app I might take this approach.
A read-only database for your official birds. This database is downloaded on first launch & whenever it needs updates. You shouldn't attempt to put this in your bundle as its going to be pretty big. It will not be backed up at any point.
A read-write database which holds your Diary entries. This database is backed to to iCloud and isnt touched across upgrades of the Bird database.
Loosely couple the two databases by using GUIDs rather than CoreData relationships.
e.g The GUID for a Mallard Duck might be
DUCK1234
. Write that GUID as a attribute (e.g birdGUID ) on your diary entry. To find all Diary entries for Mallards run a query on "birdGUID == 'DUCK1234'" on your Diary database and you get all the times you spotted one.The reason for doing this is that you can upgrade the official Bird Database without worrying about harming the user data. Say you purchase a better/cheaper database or a different one which has bird calls you can adjust the Schema to cope with that.
EDIT
One approach (an easy one) is to build your stack with two
NSPersistentStores
Im not going to fully explain this as theres many excellent Core Data tutorials but take note of setting the
NSReadOnlyPersistentStoreOption
on your Bird Database.This doesn't involve using
UIManagedDocument
as you don't get enough control over the stack.To summarise, The stack from bottom to top.
UIManagedDocument
- Model Controller. Handles File Wrapper mechanics and provides free stack. Not required . May make Multi Document apps easier (or not).NSManagedObjectModel
- Model , The Schema of your Core Data Model.NSPersistentStore
- Model , Represents a single SQLite database on disk.NSPersistentStoreCoordinator
- Controller for any number ofNSPersistentStore
NSManagedObjectContext
- Model workspace , like a piece of Note Paper. Use and save or use and discard.At this stage don't get tied up with
UIManagedDocument
. Its a controller for the file system with a CoreData stack on top. It doesn't do what you want to do out of the box.Worry about the real problem which is how to load both the databases and use their data to drive your UI.
If its really important later you can move a UIManagedDocument based architecture. If this was my app I wouldn't bother.