NSTableView + Cocoa Bindings + Core Data + Drag &...

23
NSTableView + Cocoa Bindings + Core Data + Drag & Drop HMDT Makoto Kinoshita

Transcript of NSTableView + Cocoa Bindings + Core Data + Drag &...

NSTableView + Cocoa Bindings + Core Data +

Drag & Drop

HMDT Makoto Kinoshita

NSTableView + Cocoa Bindings

NSArrayController NSMutableArray

bindingcontent

NSTableView + Cocoa Bindings + Core Data

NSArrayController delegate

bindingmanagedObjectContext

Core Data

mutableSetForKey

NSMutableSet

Array or Set

NSArray has order

NSSet has NO ORDER

Table view uses order!

Not Ordered Data

Ordered Data

Drag And Drop

date source

writeRows:toPasteboard:

acceptDrop:row:dropOperation

paste board

What We Need

Core Data model with ordering

Copy managed objects to a pasteboard

Example Model

Entity Name: MailAttributes: to (String) title (String) from (String)

Type 1. Add An Attribute For Ordering

New Attributes: order (Int32)

Sort By Order

NSSortDescriptor key: order ascending: YES selector: compare:

Dragging

date source

Core Data

NSArrayController

1. Write to pboard request

2. Get selected managed objects

paste board

3. Copy data for managed objects

… and Dropping

date source

NSArrayController

6. Update order values

7. Refresh view

paste board

4. Read data

5. Get data from the persistent coordinator

Core Data

Get NSArrayController

- (BOOL)tableView:(NSTableView*)tableView writeRows:(NSArray*)rows toPasteboard:(NSPasteboard*)pboard{ // Get array controller NSDictionary* bindingInfo; NSArrayController* arrayController; bindingInfo = [tableView infoForBinding:NSContentBinding]; arrayController = [bindingInfo valueForKey:NSObservedObjectKey];

Get Managed Objects Data // Get arranged objects, they are managed object NSArray* arrangedObjects; arrangedObjects = [arrayController arrangedObjects]; // Collect URI representation of managed objects NSMutableArray* objectURIs; NSEnumerator* enumerator; NSNumber* rowNumber; objectURIs = [NSMutableArray array]; enumerator = [rows objectEnumerator]; while (rowNumber = [enumerator nextObject]) { int row = [rowNumber intValue]; if (row >= [arrangedObjects count]) { continue; } // Get URI representation of managed object NSManagedObject* object; NSManagedObjectID* objectID; NSURL* objectURI; object = [arrangedObjects objectAtIndex:row]; objectID = [object objectID]; objectURI = [objectID URIRepresentation]; [objectURIs addObject:objectURI]; }

URI Representation

x-coredata://2D1E267F-6430-4636-A7E8-444786806A35/Mail/p109

Get With URI Representation // Get managed object context and persistent store coordinator NSManagedObjectContext* context; NSPersistentStoreCoordinator* coordinator; context = [self managedObjectContext]; coordinator = [context persistentStoreCoordinator]; // Collect manged objects with URIs NSMutableArray* managedObjects; NSEnumerator* enumerator; NSURL* objectURI; managedObjects = [NSMutableArray array]; enumerator = [objectURIs objectEnumerator]; while (objectURI = [enumerator nextObject]) { // Get managed object NSManagedObjectID* objectID; NSManagedObject* object; objectID = [coordinator managedObjectIDForURIRepresentation:objectURI]; object = [context objectWithID:objectID]; if (!object) { continue; } [managedObjects addObject:object]; }

Re-order // Get managed objects NSMutableArray* objects; objects = [NSMutableArray arrayWithArray:[arrayController arrangedObjects]]; if (!objects || [objects count] == 0) { return NO; } // Replace dragged objects with null objects as placeholder enumerator = [draggedObjects objectEnumerator]; while (object = [enumerator nextObject]) { int index; index = [objects indexOfObject:object]; if (index == NSNotFound) { // Error NSLog(@"Not found dragged link in links"); continue; } [objects replaceObjectAtIndex:index withObject:[NSNull null]]; } // Insert dragged objects at row if (row < [objects count]) { [objects insertObjects:draggedObjects atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(row, [draggedObjects count])]]; } else { [objects addObjectsFromArray:draggedObjects]; } // Remove null objeccts [objects removeObject:[NSNull null]]; // Re-order objects int i; for (i = 0; i < [objects count]; i++) { object = [objects objectAtIndex:i]; [object setValue:[NSNumber numberWithInt:i] forKey:@"order"]; } // Reload data [arrayController rearrangeObjects];

Problem

Type 2. Add An Entity For Ordering

Solution

Mail Addition

- (void)add:(id)sender{ // Create and insert Mail NSManagedObject* mail; mail = [NSEntityDescription insertNewObjectForEntityForName:@"Mail" inManagedObjectContext:[self managedObjectContext]]; // Create and insert Order NSManagedObject* order; order = [NSEntityDescription insertNewObjectForEntityForName:@"Order" inManagedObjectContext:[self managedObjectContext]]; // Set order to mail [mail setValue:order forKey:@"order"];}

Demo