objective c - NSTokenField representing Core Data to-many relationship -


i'm having problem figuring out how represent many-to-many relationship model in nstokenfield. have 2 (relevant) models:

item tag

an item can have many tags , tag can have many items. it's inverse to-many relationship.

what represent these tags in nstokenfield. end tokenfield automatically suggesting matches (found out way tokenfield:completionsforsubstring:indexoftoken:indexofselecteditem) , being able add new tag entities if wasn't matched existing one.

okay, hope you're still me. i'm trying bindings , array controllers (since makes sense, right?)

i have array controller, "item array controller", bound app delegates managedobjectcontext. tableview showing items has binding array controller.

my nstokenfield's value has binding array controllers selection key , model key path: tags.

with config, nstokenfield won't show tags. gives me:

<nstokenfieldcell: 0x10014dc60>: unknown object type assigned (relationship objects {(     <nsmanagedobject: 0x10059bdc0> (entity: tag; id: 0x10016d6e0 <x-coredata://9d77d47a-1171-4397-9777-706f599d7e3b/tag/p102> ; data: <fault>) )} on 0x100169660).  ignoring... 

this makes sense me, no worries. i've looked @ of nstokenfield delegate methods , seems should use:

- (nsstring *)tokenfield:(nstokenfield *)tokenfield displaystringforrepresentedobject:(id)representedobject 

problem is, method not called , same error before.

alright, next move try , make valuetransformer. transforming array tag entity -> array strings (tag names) good. other way more challenging.

what i've tried every name in shared app delegate managed object context , return matching tags. gives me problem different managed object contexts apparently:

illegal attempt establish relationship 'tags' between objects in different contexts (source = <nsmanagedobject: 0x100156900> (entity: item; id: 0x1003b22b0 <x-coredata://9d77d47a-1171-4397-9777-706f599d7e3b/item/p106> ; data: { author = "0x1003b1b30 <x-coredata://9d77d47a-1171-4397-9777-706f599d7e3b/author/p103>"; createdat = nil; filepath = nil; tags =     ( ); title = "great presentation"; type = "0x1003b1150 <x-coredata://9d77d47a-1171-4397-9777-706f599d7e3b/type/p104>"; }) , destination = <nsmanagedobject: 0x114d08100> (entity: tag; id: 0x100146b40 <x-coredata://9d77d47a-1171-4397-9777-706f599d7e3b/tag/p102> ; data: <fault>)) 

where going wrong? how resolve this? right approach (seems weird me woud have use valuetransformer?)

thanks in advance!

i've written custom nsvaluetransformer map between bound nsmanagedobject/tag nsset , nsstring nsarray of token field. here 2 methods:

- (id)transformedvalue:(id)value {   if ([value iskindofclass:[nsset class]]) {     nsset *set = (nsset *)value;     nsmutablearray *ary = [nsmutablearray arraywithcapacity:[set count]];     (tag *tag in [set allobjects]) {       [ary addobject:tag.name];     }     return ary;   }   return nil; }  - (id)reversetransformedvalue:(id)value {   if ([value iskindofclass:[nsarray class]]) {     nsarray *ary = (nsarray *)value;     // check each nsstring in array representing tag name if corresponding     // tag managed object exists     nsmutableset *tagset = [nsmutableset setwithcapacity:[ary count]];     (nsstring *tagname in ary) {       nsmanagedobjectcontext *context = [[nsapp delegate] managedobjectcontext];       nsfetchrequest *request = [[nsfetchrequest alloc] init];        nspredicate *searchfilter = [nspredicate predicatewithformat:@"name = %@", tagname];       nsentitydescription *entity = [nsentitydescription entityforname:[tag classname] inmanagedobjectcontext:context];        [request setentity:entity];       [request setpredicate:searchfilter];        nserror *error = nil;       nsarray *results = [context executefetchrequest:request error:&error];       if ([results count] > 0) {         [tagset addobjectsfromarray:results];       }       else {         tag *tag = [[tag alloc] initwithentity:entity insertintomanagedobjectcontext:context];         tag.name = tagname;          [tagset addobject:tag];         [tag release];       }     }     return tagset;   }   return nil; } 

coredata seems automatically establish object relationships on return (but have not verified yet)

hope helps.


Comments

Popular posts from this blog

ASP.NET/SQL find the element ID and update database -

jquery - appear modal windows bottom -

c++ - Compiling static TagLib 1.6.3 libraries for Windows -