FROM : mmalcolm crawford
DATE : Sun May 01 00:09:38 2005
On Apr 30, 2005, at 7:38 AM, Paul Mix wrote:
>> Xcode already provides a template -- "Core Data Application"-- to
>> start down this path. It provides a single-window application
>> where the persistent store coordinator is set up and managed by an
>> application delegate. You could extract the part of the -
>> managedObjectContext method that creates the coordinator and use
>> it to implement a -coordinator method (as illustrated below). You
>> are free then to add as many managed object contexts as you wish...
>
> Thanks for the feedback. Allow me to revise my idiom a bit further.
> A better analogy for the app I was planning would possibly be a
> "Library" type of app, with two types of stores: a single,
> centralized "Library" of media (books, cd's, etc.) (stored within
> the app bundle or an Application Support directory), and multiple
> "Personnel" document files (one for each person, that could be
> saved and moved anywhere by the end-user). All details specific to
> each Person would be stored in the "Person" document file, but
> would have references to entities defined in the centralized
> "Library" database. [...]
> My plan was to use an NSPersistentDocument for the "Person"
> documents (one person, one file/store, one "document" types), but
> was unsure how to handle the editors for the "Library" items (many
> items, one file/store, multiple "document" types).
>
Again *if* I understand correctly what you want, then it's reasonably
straightforward.
To edit the library, you could create a "Core Data Application".
You need change the path to the data store to point wherever is
appropriate (per - (NSString *)applicationSupportFolder), and then
you could just use the single application-wide editing context the
template creates for you and reference it from as many window
controllers as you wish.
[data store] -- [p.s.c.] -- [m.o.c.] -- [window controller] (books)
(file) |---- [window controller] (CDs)
|---- [window controller] (DVDs)
The downside to this (singe context) approach that you probably
anticipated is that is gives you a single "editing context" or
scratch pad (to use the analogy here: <http://developer.apple.com/
documentation/Cocoa/Conceptual/CoreData/Articles/cdBasics.html>). If
you make edits to instances of two type of media in two separate
windows, then a 'save' commits changes in both.
The advantage to the architecture you suggested, and outlined in the
previous reply, is that you're able to keep changes discrete per
window, and save independently:
[data store] -- [p.s.c.] -- [m.o.c.] -- [window controller] (books)
(file) |----- [m.o.c.] -- [window controller] (CDs)
|----- [m.o.c.] -- [window controller] (DVDs)
A potential disadvantage here is that if there are any relationships
between books, CDs, and/or DVDs, then you may at some stage have a
situation where changes made in one window are inconsistent with
changes recently saved by another, and a user may unwittingly
overwrite those changes. Optimistic locking won't help you here
because you have a single persistence stack. This is a rather subtle
point...
For the Person documents, you can create a standard "Core Data
Document-based Application", but configure the persistence stack so
that in addition to the document's store you also use the library store:
[document file] -- [p.s.c.] -- [m.o.c.] -- [document controller]
[library] ----|
There are two places in which you need to configure the stack. The
obvious one is the aptly-named:
- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url ofType:
(NSString *)fileType error:(NSError **)error
You can override the method to add a persistent store to the
coordinator:
- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url ofType:
(NSString *)fileType error:(NSError **)error
{
if (![super configurePersistentStoreCoordinatorForURL:url
ofType:fileType error:error])
{
return NO;
}
NSPersistentStoreCoordinator *coordinator =
[[self managedObjectContext] persistentStoreCoordinator];
libraryStore =
[coordinator addPersistentStoreWithType:STORE_TYPE
configuration:nil
URL:url // path library
options:nil
error:&error];
// implementation continues...
Note, however, that this method is invoked when an *existing*
document is first opened and when a *new* document is first saved.
Clearly, then, overriding this method isn't much help for new
documents... To address this issue, you also need to override:
- (id)initWithType:(NSString *)type error:(NSError **)error;
It should add the persistent store in the same way as configure...
So: (a) It may be worth factoring this code into a separate method;
(b) In your configure... method, or the factored method, you need to
ensure that the store hasn't already been added.
- (BOOL)addLibraryStore:(NSError **)error
{
NSURL *url = // URL for your library
NSPersistentStoreCoordinator * coordinator =
[[self managedObjectContext] persistentStoreCoordinator];
id store = [coordinator persistentStoreForURL: url];
if (store == nil) {
store =
[coordinator addPersistentStoreWithType:STORE_TYPE
configuration:nil
URL:url
options:nil
error:error];
if (store == nil) {
return NO;
}
}
return YES;
}
Note that after all this, the biggest issue you face will I suspect
be creating cross-store relationships (more anon)...
mmalc
(All code typed in Mail, so usual caveats apply.)
DATE : Sun May 01 00:09:38 2005
On Apr 30, 2005, at 7:38 AM, Paul Mix wrote:
>> Xcode already provides a template -- "Core Data Application"-- to
>> start down this path. It provides a single-window application
>> where the persistent store coordinator is set up and managed by an
>> application delegate. You could extract the part of the -
>> managedObjectContext method that creates the coordinator and use
>> it to implement a -coordinator method (as illustrated below). You
>> are free then to add as many managed object contexts as you wish...
>
> Thanks for the feedback. Allow me to revise my idiom a bit further.
> A better analogy for the app I was planning would possibly be a
> "Library" type of app, with two types of stores: a single,
> centralized "Library" of media (books, cd's, etc.) (stored within
> the app bundle or an Application Support directory), and multiple
> "Personnel" document files (one for each person, that could be
> saved and moved anywhere by the end-user). All details specific to
> each Person would be stored in the "Person" document file, but
> would have references to entities defined in the centralized
> "Library" database. [...]
> My plan was to use an NSPersistentDocument for the "Person"
> documents (one person, one file/store, one "document" types), but
> was unsure how to handle the editors for the "Library" items (many
> items, one file/store, multiple "document" types).
>
Again *if* I understand correctly what you want, then it's reasonably
straightforward.
To edit the library, you could create a "Core Data Application".
You need change the path to the data store to point wherever is
appropriate (per - (NSString *)applicationSupportFolder), and then
you could just use the single application-wide editing context the
template creates for you and reference it from as many window
controllers as you wish.
[data store] -- [p.s.c.] -- [m.o.c.] -- [window controller] (books)
(file) |---- [window controller] (CDs)
|---- [window controller] (DVDs)
The downside to this (singe context) approach that you probably
anticipated is that is gives you a single "editing context" or
scratch pad (to use the analogy here: <http://developer.apple.com/
documentation/Cocoa/Conceptual/CoreData/Articles/cdBasics.html>). If
you make edits to instances of two type of media in two separate
windows, then a 'save' commits changes in both.
The advantage to the architecture you suggested, and outlined in the
previous reply, is that you're able to keep changes discrete per
window, and save independently:
[data store] -- [p.s.c.] -- [m.o.c.] -- [window controller] (books)
(file) |----- [m.o.c.] -- [window controller] (CDs)
|----- [m.o.c.] -- [window controller] (DVDs)
A potential disadvantage here is that if there are any relationships
between books, CDs, and/or DVDs, then you may at some stage have a
situation where changes made in one window are inconsistent with
changes recently saved by another, and a user may unwittingly
overwrite those changes. Optimistic locking won't help you here
because you have a single persistence stack. This is a rather subtle
point...
For the Person documents, you can create a standard "Core Data
Document-based Application", but configure the persistence stack so
that in addition to the document's store you also use the library store:
[document file] -- [p.s.c.] -- [m.o.c.] -- [document controller]
[library] ----|
There are two places in which you need to configure the stack. The
obvious one is the aptly-named:
- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url ofType:
(NSString *)fileType error:(NSError **)error
You can override the method to add a persistent store to the
coordinator:
- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url ofType:
(NSString *)fileType error:(NSError **)error
{
if (![super configurePersistentStoreCoordinatorForURL:url
ofType:fileType error:error])
{
return NO;
}
NSPersistentStoreCoordinator *coordinator =
[[self managedObjectContext] persistentStoreCoordinator];
libraryStore =
[coordinator addPersistentStoreWithType:STORE_TYPE
configuration:nil
URL:url // path library
options:nil
error:&error];
// implementation continues...
Note, however, that this method is invoked when an *existing*
document is first opened and when a *new* document is first saved.
Clearly, then, overriding this method isn't much help for new
documents... To address this issue, you also need to override:
- (id)initWithType:(NSString *)type error:(NSError **)error;
It should add the persistent store in the same way as configure...
So: (a) It may be worth factoring this code into a separate method;
(b) In your configure... method, or the factored method, you need to
ensure that the store hasn't already been added.
- (BOOL)addLibraryStore:(NSError **)error
{
NSURL *url = // URL for your library
NSPersistentStoreCoordinator * coordinator =
[[self managedObjectContext] persistentStoreCoordinator];
id store = [coordinator persistentStoreForURL: url];
if (store == nil) {
store =
[coordinator addPersistentStoreWithType:STORE_TYPE
configuration:nil
URL:url
options:nil
error:error];
if (store == nil) {
return NO;
}
}
return YES;
}
Note that after all this, the biggest issue you face will I suspect
be creating cross-store relationships (more anon)...
mmalc
(All code typed in Mail, so usual caveats apply.)
| Related mails | Author | Date |
|---|---|---|
| James Clause | Apr 29, 16:49 | |
| John Brownlow | Apr 29, 17:36 | |
| Scott Stevenson | Apr 29, 19:07 | |
| John Timmer | Apr 29, 22:34 | |
| John Timmer | Apr 29, 23:28 | |
| Bill Bumgarner | Apr 30, 00:00 | |
| John Timmer | Apr 30, 00:29 | |
| Scott Ellsworth | Apr 30, 00:43 | |
| Chris Hanson | Apr 30, 00:56 | |
| Paul Mix | Apr 30, 01:03 | |
| John Timmer | Apr 30, 01:13 | |
| Scott Stevenson | Apr 30, 01:15 | |
| Scott Stevenson | Apr 30, 01:18 | |
| mmalcolm crawford | Apr 30, 01:47 | |
| Bill Bumgarner | Apr 30, 09:49 | |
| Paul Mix | Apr 30, 16:38 | |
| mmalcolm crawford | May 1, 00:09 |






Cocoa mail archive

