Re: Core data model - binding question
Re: Core data model - binding question
- Subject: Re: Core data model - binding question
- From: Davide Benini <email@hidden>
- Date: Wed, 14 Sep 2005 23:09:24 +0200
Thanks a million John, you are giving me such an invaluable help in
focusing where the real trouble is.
Sorry for giving little details at first, I didn't realise how linked
to the data structure this problem is.
I'll try to explain why my interface data is not consonant with my
data structure. The interface whose snapshot are illustrated here
( http://www.cnomania.it/garage/appreference.htm ) is "half" of my
GUI. As you see there are 2 tabs; the first one is used to introduce
data in the database, the second one (the one we are discussing) is
for just browsing. This app is targeted at academic researchers, me,
in particular; its aim is to keep all of my phd annotations together.
This is why every passage (which is actuallly a note, or a quote ) is
linked to a specific entry (a book, or an article, or a web page).
The Topic entity represents a thematic flag: a quote might be linked
to "chaos theory", "indeterminacy" and "jakobson linguistic". So each
passage is linked to one or more quotes.
My browser GUI, the one I am discussing here, is meant at exploring
my notes in a different, and more natural way. You wonder, "where did
I read about indeterminacy?" and boom you see the authors you have
read, and then you choose the book, and then you read the note you
took. This is why this interface is "twisted". I guess this is the
same metaphor that is behind iTunes: genres, author, album, song, but
I think the data model follows another order...
Now I am really wondering if there is a better way to structure the
data. I had planned to add an independent author entity in a more
advanced development stage; I am still learning, and I wanted to add
authors in elegant way, with a NSFormatter to recognise name and
surname. Do you think I should add an author entity right now? Should
this Author entity be linked to both book and passages, maybe as a
fetched property?
Thanks again,
Davide
Il giorno 14/set/05, alle ore 22:28, John Timmer ha scritto:
The allObjects message should have been sent to an NSMutableSet
(produced by
the "mutableSetValueForKey" message), not to an individual managed
object.
That's why you get the error.
The mistake I made is that each passage has a to-one relationship with
entry.author. What you want is to shift the code I wrote down to
the topic
level. So, in the topic class, the following would probably work:
- (NSArray *) allAuthors {
NSArray *theReturn = [[self mutableSetValueForKey: @"passages"]
allObjects];
theReturn = [theReturn valueForKeyPath:
@"entry.distinctUnionOfObjects.author"];
return theReturn;
}
The problem here is that you will just wind up with an array of
strings,
which won't get you back to whatever text you want populating the
third box
if that depends on the author selected (unless you filter an array of
entries using the author key). A problem I'm having in terms of
suggesting
anything is understanding how things in your interface are linked,
and what
they represent. Topic and author are easy, but I don't know what
goes in
text, and how that is dependent on the selection of author or
topic. Same
thing for passage.
As you say, there may be a structural problem with your data model,
given
that it doesn't mesh well with the interface. If this browser is the
primary way your user will interact with this data, then you should
think
about structuring the data to mesh better with the interface. You
are also
thinking in a linear manner - both topic and entry can have
relationships to
a separate author object, if you need to.
I would recommend sticking with bindings - they cut down on all the
change
observations and undo worries that you have otherwise.
JT
I tried your solution, but I get an error message saying that my
entry object (a NSManagedObject subclass) cannot accept the allObject
message. The code you provided is somehow inconsistent with my data
model, shown here:
http://www.cnomania.it/garage/appreference.htm
I tried to debug in many ways, changing bindings in both the
controller and the table column, but I am almost 100% sure that there
is a conceptual mistake in this approach. Each passage is linked to a
single book, but some authors have more than one book in my database:
that is where duplication comes from.
I tried to subclass the NSArrayController class, but this is odd and
difficult (everyone seems to say that on the web); then I thought I
should probably be content with subclassing NSTableView. In fact my
problem is just in the UI: if I manage to get the table shows each
author just once it is enough. What is more, by subclassing just the
table view I leave the array untouched, and this is crucial to keep
make the filtering action of the browser effective.
At any rate I feel that this filtering process trhough cocoa bindings
is getting more complicated than I expected; the third column, for
example, will be limited both by the first column AND by the second
column... I am wondering fillling the table programmatically would be
any easier...
What do ye folks think? Any smart and compact way to avoid
duplication and keep the filtering action effective?
Cheers,
Davide
Thanks for your suggestion, it works perfectly.
I bind the array controller to selection.passages and the column of
the table to book.author.
Now my problem is eliminating duplicates: when a topic is
associated
to more than one passage of the same book I get the author name
duplicated in the table. I tried t bind the table column to
email@hiddenr, but I get this message in the
log:
2005-09-14 10:53:42.431 BiblioBeta[21410] [<BibliographicEntry
0x3182a0> valueForUndefinedKey:]: this class is not key value
coding-
compliant for the key @distinctUnionOfArrays.
I also tried to put the @distinctUnionOfArrays in different
positions, but I get the same log, and the table doesn't work.
Any suggestion?
Yes. The problem with array operators like @distinctUnion and
@count are
that they are effectively read-only, while key/value coding
requires it to
be read-write. The trick is to hide the array operator behind some
other
code that provides both getter/setter methods.
In this case, I'd recommend making your passage object an
NSManagedObject
subclass, and add code something like:
- (NSArray *) distinctAuthors {
return [[[self mutableSetValueForKey: @"authors"] allObjects]
valueForKey: @"distinctUnionOfArrays.author"];
}
- (void) setDistinctAuthors {
return;
}
(note - I wrote the return line from memory, so check syntax on
that)
This allows the distinct array to be key/value coding compliant.
_______________________________________________
This mind intentionally left blank
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden