Drag and drop in table view using core data

Discussion in 'Mac Programming' started by Monaj, May 6, 2011.

  1. macrumors regular

    Joined:
    May 24, 2009
    #1
    Hi all,
    I have made an application in which I am using core-data, array-
    controllers to show data in two tables, such that -

    table1 => entity: table1Entity (attributes: detail)
    table2 => table2Entity (from, to, detail)

    Now I am trying to perform drag from table1 and drop on table2, such
    that an entity added to array controller of table2 contains value of
    attribute - 'detail' from table1Entity, which is dropped.

    I know that we can add an entity to an array controller subclass in
    following way-

    Code:
    NSManagedObjectContext *mangagedObjectContext = [self 
    managedObjectContext]; 
    NSString *entityName = [self entityName]; 
    NSManagedObjectModel *managedObjectModel = [[mangagedObjectContext 
    persistentStoreCoordinator] managedObjectModel]; 
    NSEntityDescription *entity = [[managedObjectModel entitiesByName] 
    objectForKey:entityName]; 
    id newObject = [[NSManagedObject alloc] initWithEntity:entity 
    insertIntoManagedObjectContext:mangagedObjectContext]; 
    [self addObject:newObject];
    But

    I am not getting, how can we extract information from dropped
    object(NSManagedObject) and modify the entity(NSEntityDescription)
    using it.

    Can anyone suggest me how to do it?

    Thanks,

    Monaj
     
  2. macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #2
    Check out the Using Drag and Drop in Table chapter for the Table View Programming Guide.

    Once you actually have the dropped object (I'll call it droppedObject), you'd only need to augment your code with:
    Code:
    newObject.detail = droppedObject.detail;
    
    Note that when you have a core data object, you actually have a NSManagedObject subclass which Core Data has dynamically generated. This subclass will have declared properties implemented corresponding to the properties of the relevant entity.

    Also note that an NSEntityDescription is only metadata. It's analogous to a class. You don't set property values in an NSEntityDescription. You only set property values in a NSManagedObject init'ed using the NSEntityDescription.

    Finally, my advice would be to implement this first using a button. The user selects row(s) in table1 and then clicks the button. This will let you nut out the Core Data issues without the complication of the drag and drop protocols and pasteboards. Once you've got that working, try for drag'n'drop.
     
  3. Monaj, May 8, 2011
    Last edited: May 8, 2011

    thread starter macrumors regular

    Joined:
    May 24, 2009
    #3
    Hi jiminaus,

    Thanks for the reply :)

    I did what you suggested :

    but it is not working for me :(

    Below is the code which I am using:

    Code:
    - (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info
    
                  row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation
    
    {
        
        NSPasteboard* pboard = [info draggingPasteboard];
        
        NSData* rowData = [pboard dataForType:taskExchangeDataType];
        
        NSIndexSet* rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:rowData];
        [rowIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
            NSManagedObject *droppedObject = [[toDoController arrangedObjects] objectAtIndex:idx];
            
            NSManagedObjectContext *mangagedObjectContext = [self managedObjectContext];
            entityName = [self entityName];
            NSManagedObjectModel *managedObjectModel = [[mangagedObjectContext persistentStoreCoordinator] managedObjectModel];
            NSEntityDescription *entity = [[managedObjectModel entitiesByName] objectForKey:entityName];
            NSManagedObject *newObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:mangagedObjectContext];
            newObject.detail = droppedObject.detail; //error: property 'detail' not found on object of type 'NSManagedObject *'
            [self addObject:newObject];
            
        }];
        
        return YES;
    }

    It is giving error on this line:

    Code:
    newObject.detail = droppedObject.detail; //error: property 'detail' not found on object of type 'NSManagedObject *'
    I think it is giving this error because 'detail' is an attribute.

    Please suggest !

    Thanks,

    Monaj
     
  4. macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #4
    Error or warning? It's right that NSManagedObject doesn't have a detail property, so a warning like this would be expected.

    Try keeping it declarad as type id like this:
    Code:
    id newObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:mangagedObjectContext];
    
    BTW What class is this code from? The line entityName = [self entityName]; seems to suggest it's inside a model object. That would be rather peculiar. If it's is inside a controller, then this line is possibly wrong.
     

Share This Page