• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Core Data compound keys
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Core Data compound keys


  • Subject: Re: Core Data compound keys
  • From: Conor <email@hidden>
  • Date: Thu, 02 Aug 2007 01:26:40 +0200

Since nobody more experienced has responded to your mailing I would suggest
that you build the tag checking into a subclass of NSManagedObject. You set
the Core Data object articles to the subclass and then implement a set and
get tags method that stores the tags in a many to many relationship, while
checking that they only link once. It would go something like this:

- (NSString *)tags {

     NSSet *tagsSet = [self valueForKey:@"tagsSet"];

    if ([tagsSet count] != 0) {
        NSMutableString *tagsString = [NSMutableString string];
        NSArray *tagsArray = [tagsSet allObjects];
        tagsArray = [tagsArray sortedArrayUsingDescriptors:[NSArray
arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:@"name"
ascending:YES] autorelease]]];

        NSEnumerator *tagsEnum = [tagsArray objectEnumerator];
        NSString *nextTagName;
        while (nextTagName = [[tagsEnum nextObject] valueForKey:@"name"]) {
            if ([tagsString length])
                [tagsString appendString:@", "];
            [tagsString appendString:nextTagName];
        }

        return tagsString;
    }

     return nil;
}

 - (void)setTags:(NSString *)aString {

    if ((aString == nil && [[self primitiveValueForKey:@"tagsSet"] count] ==
0) || [aString isEqualToString:[self tags]])
        return;

    NSMutableSet *tagsSet = [self mutableSetValueForKey:@"tagsSet"];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Tag"
inManagedObjectContext: managedObjectContext];

    NSArray *tags = [aString componentsSeparatedByString:@", "];
    NSMutableSet *tagsAdded = [NSMutableSet set];

    NSError *fetchError;
    NSFetchRequest * fetch = [[NSFetchRequest alloc] init];
    [fetch setEntity: entity];

     NSEnumerator *tagsEnum = [tags objectEnumerator];
     NSString *nextTagName;
     while (nextTagName = [tagsEnum nextObject]) {

         NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name
like[c] %@", nextTagName];
         [fetch setPredicate: predicate];

         NSArray * results = [managedObjectContext executeFetchRequest:fetch
error:&fetchError];

         //Fetch succesfull
         if ([results count]) {
             if (![tagsSet containsObject:[results objectAtIndex:0]]) {
                 [tagsSet addObject:[results objectAtIndex:0]];
             }
             [tagsAdded addObject:[results objectAtIndex:0]];
         }
         else if ([results count] == 0) {
             //Create new Tag
             NSManagedObject* aTag = [NSEntityDescription
insertNewObjectForEntityForName:@"Tag" inManagedObjectContext:
managedObjectContext];
             [aTag setValue:nextTagName forKey:@"name"];
             [tagsSet addObject: aTag];
             [tagsAdded addObject: aTag];

         }
         else if (results == nil) {
             NSLog(@"Fetch Error setTagsString: %@ reason: %@ with: %@",
[fetchError localizedDescription], [fetchError localizedFailureReason],
fetch);
         }
     }
     [fetch release];


     //remove any tags that were deleted and are not present in the Set of
tagsAdded we just created
     NSEnumerator *tagsObjectsEnum = [tagsSet objectEnumerator];
     NSManagedObject *nextTag;
     while (nextTag = [tagsObjectsEnum nextObject]) {
         if (![tagsAdded containsObject:nextTag]) {
             [tagsSet removeObject: nextTag];
             if ([[nextTag primitiveValueForKey:@"entries"] count] == 0)
                 [managedObjectContext deleteObject:nextTag];
         }
     }
 }

Type in mail, so check for typos and the such. But this would be the general
idea. The many to many relationship is to a key tagsSet that is an object
that has an attribute with key name. In this case I am turning the tags into
a coma separated string to present to the user; so I would also go further
and save the results as a transient attribute for caching. I also just
started with Core Data so I am not talking from experience.

Regards,
Conor
http://www.bruji.com/


_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Prev by Date: Re: dynamically adding NSTableColumns while using bindings
  • Next by Date: Re: How to be notified of scrolling an NSTableView
  • Previous by thread: Core Data compound keys
  • Next by thread: How to access PersistentDocument data store from MainMenu
  • Index(es):
    • Date
    • Thread