userInfo

Tags ( )

For user defined columns should we be using the methods:

MIEntryData
-userInfoForKey
-setUserInfo

rather than the valueForKey and setValue methods?

as noted in another thread (mGTD = validation errors), I've been using the valueForKey and setValue for custom mGTD columns but if those columns are not present (e.g. the user didn't add them) the resulting errors are not good.

Thanks
Jeff

I'm not sure, what are you

I'm not sure, what are you trying to store? In general the userInfo values are not visible to the user, they are meant for metadata about the entry and as extra storage place. For example smart folder entries use the user info to store things like the smart folder query and settings such as "include trash". It's mean to be an extra data store, but not one that will be really visible to the user, available in searches, or anything like that.

From all that I think using the value for key methods is probably still what you want. I didn't quite understand the validating errors discussion, what exactly is causing the problem?

Hi, from the name "userInfo"

Hi,

from the name "userInfo" I thought that maybe that was meant to indicate that these were the methods for user defined columns (custom columns). But from your description it seems completely different.

The problem is when people haven't set up all the columns that mGTD expects, and then mGTD will try to set or access a value that doesn't exist.

for example
[entryData setValue:naString forKey:@"GTD"]

when there is no column GTD

I think that this is causing problems for some people.

as always
thanks

In the cocoa frameworks

In the cocoa frameworks "userInfo" is often used to add extra data to objects, for example look at NSNotification. The trick is that the user in these cases is you the developer, not the actual application user.

Here's a way you might solve the missing column problem. You can just check ahead of time and see if the notebook contains the columns that you need. To do that you'll want to do something like this: (typos likely included)

NSManagedObject *context = [document managedObjectContext];
NSPersistentStoreCoordinator *storeCoordinator = [context persistentStoreCoordinator];
NSManagedObjectModel* managedObjectModel = [storeCoordinator managedObjectModel];
NSEntityDescription *entryDataEntity = [[[document managedObjectModel entitiesByName] objectForKey:@"EntryData"];
NSDictionary *entryDataAttributesByName = [entryDataEntity attributesByName];

// and finnally

if ([entryDataAttriubtesByName valueForKey:@"GTD"] != null) {
// safe to call [entryData setValue:naString forKey:@"GTD"]
}

Thanks, for helping me out

Thanks, for helping me out so explicitly.

Can I ask what might be a stupid question?

Can I override the entryData's valueForKey and setValue methods so that they would include such checks for the column's existence and then pass the message on to Mori entryData's setValue methods? If so, where would I put that?

I think I could better

I think I could better rephrase the question to be:

in terms of good programming style, which object would make the most sense to implement such a check?

Off the top of my head I could think of two places:

1. override the natural "setValue" and "valueForKey" methods so that when my objects message an entryData for the column values, the checks are included. (this is what I was trying to ask above.)

2. Have my main controller object implement a check and return a boolean value:

for example:

- (BOOL) columnExists:(NSDocument)doc :(NSString)key {
NSManagedObject *context = [document managedObjectContext];
NSPersistentStoreCoordinator *storeCoordinator = [context persistentStoreCoordinator];
NSManagedObjectModel* managedObjectModel = [storeCoordinator managedObjectModel];
NSEntityDescription *entryDataEntity = [[[document managedObjectModel entitiesByName] objectForKey:@"EntryData"];
NSDictionary *entryDataAttributesByName = [entryDataEntity attributesByName];
if ([entryDataAttriubtesByName valueForKey:@"GTD"] != null) {return YES}

else {return NO};
}

then use this to check each time:

if ([gtdController columnExists:document :key]){
[entryData setValue:naString forKey:@"GTD"]
}

If possible, I think #1 would be easier because then I can just use the getValue and setValue methods naturally (I wouldn't have to go back and add the if-then statements each time I want to use a custom-column value).

Thanks again, (no real hurry on this one; I'm going to assume for the moment that all mGTD users can properly set up columns or use the example notebook)

Actually I think choice 2.

Actually I think choice 2. is the best solution. There isn't a good way for plugins to subclass existing classes, so it's not really practical to override valueForKey.

Is it not possible to add

Is it not possible to add methods to a class using categories?

You can add methods that

You can add methods that don't already exist, but you can't subclass methods (or you can't put it's problematic, and you shouldn't really shouldn't).

So could I add mgSetValue

So could I add mgSetValue and mgValueForKey, that would include checks for the columns and then pass on a normal setValue call to entryData?

Yeah that should work fine I

Yeah that should work fine I think.

Hi Jesse, Could you go over

Hi Jesse,

Could you go over the code you posted one time:

NSManagedObject *context = [document managedObjectContext];
NSPersistentStoreCoordinator *storeCoordinator = [context persistentStoreCoordinator];
NSManagedObjectModel* managedObjectModel = [storeCoordinator managedObjectModel];
NSEntityDescription *entryDataEntity = [[[document managedObjectModel entitiesByName] objectForKey:@"EntryData"];
NSDictionary *entryDataAttributesByName = [entryDataEntity attributesByName];

There seems to be something wrong in the line beginning "NSEntityDescription..."

either there should be a bracket after manangedObjectModel or delete the "[document"

I just couldn't get things to work. If I make it:

[[[document managedObjectModel] entitiesByName] objectForKey:@"EntryData"]

I wondered why the calls above it were necessary, if I could get the managedObjectModel directly from the document object.

Is there a different managedObjectModel to get from the storeCoordinator?

Sorry, I tried all the combinations that I could think of and still could get things to work.

Thanks for any advice.
Jeff

also, should the first line

also, should the first line be declared "NSManagedObjectContext" ?

Thanks

Sorry about that, yes

Sorry about that, yes "[[[document managedObjectModel] entitiesByName] objectForKey:@"EntryData"]" should do the same thing. I didn't realize that the method [document managedObjectModel] existed. Err I wrote it I guess, but I had forgotten about it :)

> also, should the first line be declared "NSManagedObjectContext" ?

Opps again, yes.

Jesse

No Problem, You warned me:

No Problem,

You warned me: "typos likely included," so I was careful about things. I just wanted to make sure that I found the fixes.

Thanks,
Jeff

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.