All methods are updated to Mac OS 10.6.

Drag & Drop

Follow this steps to use drag & drop in NSTableView:

  • Create a custom view controller class MyTableViewController based on NSViewController
  • Add a new XIB based on an empty view and assign the newly added class to its File’s Owner
  • Drop in a NSTableView and assign its dataSource outlet to File’s Owner
  • Use Core Data for populating the table
  • Define a custom pasteboard type (only if you aren’t using standard types):
    NSString *MyCustomPBoardType = @"MyCustomBoardType";
  • In your view controller’s awakeFromNib method add the following lines:
    NSArray *dragTypes = [NSArray arrayWithObjects: MyCustomPBoardType,nil];
    [myTableView registerForDraggedTypes:dragTypes];
    [myTableView  setDraggingSourceOperationMask:NSDragOperationCopy forLocal:NO];
  • Implement the tableView:writeRowsWithIndexes:toPasteboard: method to handle dragging and tableView:validateDrop:proposedRow:proposedDropOperation: and tableView:acceptDrop:row:dropOperation: to handle dropping:
    - (BOOL)tableView:(NSTableView *)tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard*)pboard
    {
    	NSArray	*selectedObjects = [myArrayController selectedObjects];
    	[pboard declareTypes:[NSArray arrayWithObjects:MyCustomPBoardType,nil] owner:self];
    	for( NSManagedObject *object in selectedObjects )
    		[pboard writeObjects:[NSArray arrayWithObject:[[object objectID] URIRepresentation]]];
     
        return YES;
    }
     
    - (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)op  
     
    {
    	if ([info draggingSource] == tv) 
    	{
    		[tv setDropRow:row dropOperation:NSTableViewDropAbove];
    		return NSDragOperationNone;
    	}
    	else {
    		return NSDragOperationCopy;
    	}
     
        return NSDragOperationNone;
    }
     
    - (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info row:(int)row dropOperation:(NSTableViewDropOperation)operation
    {
    	BOOL	acceptDrop = NO;
     
    	if( [info draggingSource] == aTableView )
    		return acceptDrop;   // it allows only drops from external sources
     
    	NSArray			*classes = [[NSArray alloc] initWithObjects:[NSURL class], nil]; 
    	NSDictionary	*options = [NSDictionary dictionary];
    	NSArray			*copiedItems = [[info draggingPasteboard] readObjectsForClasses:classes options:options];
    	if( !copiedItems )
    		return acceptDrop;
     
    	// do whatever you like with copied items
    	NSArray	*currentEvents = [objectsArrayController selectedObjects];
    	for( NSManagedObject *event in currentEvents )
    	{
    		NSSet	*attendants = [event valueForKey:@"attendants"];
    		NSMutableSet	*newAttendants = [[[NSMutableSet alloc] initWithCapacity:0] autorelease];
    		[newAttendants setSet:attendants];
    		for( NSURL *copiedObject in copiedItems )
    			[newAttendants addObject:[self.managedObjectContext objectWithID:[[self.managedObjectContext persistentStoreCoordinator] managedObjectIDForURIRepresentation:copiedObject]]];
    		[event setValue:newAttendants forKey:@"attendants"];
    		acceptDrop = YES;
    	}
    	return acceptDrop;
    }

Edit Menu Validation

The simplest way to validate cut:, copy: and paste: actions for rows in a table without subclassing NSTableView is to delegate the view controller.

  • The responder chain will ask first the NSTableView object and then will look for the next responder. So it’s simple to set the view controller as the next responder in your awakeFromNib method:
    [myTableView setNextResponder:self];
  • Now implement the request actions in your view controller:
    - (IBAction)copy:(id)sender
    {
    ...
    }
     
    - (IBAction)cut:(id)sender
    {
    ...
    }
     
    - (IBAction)paste:(id)sender
    {
    ...
    }
    // and whatever you like
  • Validate the interface:
    - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem 
    {
        if ([anItem action] == @selector(copy:)) {
    		return [self canCutCopyDeleteOrDuplicate];
    	}
        return YES;
    }
  • Useful links

    NSTableView
    Drag And Drop

    { 0 comments }

40 giorni di WiFiPhoto

by admin on 13 ottobre 2009

US-AppStore-Staff-PicksWiFiPhoto è ormai in vendita da 40 giorni. Qualche frustrazione, molte soddisfazioni. All’inizio non sapevo che aspettarmi. Appena dopo il rilascio ho scoperto di aver fatto un terrible errore. Quando si invia un’applicazione ad Apple, si può indicare la data di rilascio. Io avevo scelto di lasciare la data di invio, 22 agosto. WiFiPhoto è andato online il 4 settembre. Non sapevo che avrei potuto cambiare la data di rilascio: la mia applicazione era sepolta tra tonnellate di altre applicazioni e non aveva ricevuto nessuna visibilità dal fatto di essere stata appena pubblicata. Una dura lezione che ho imparato a mie spese. Ho subito inviato una nota informativa a Macity uno dei siti per Mac e iPhone più popolari qui in Italia (forse il più popolare guardando le statistiche di Alexa). Le mie vendite sono decollate subito. In una settimana avevo venduto 2000 applicazioni solo in Italia. Anche gli amici giapponesi mi hanno dato soddisfazione: alcuni blogger mi hanno fatto una buona recensione ed è servita un sacco. In verità ero in primo luogo interessato agli Stati Uniti ma all’inizio le cose erano molto difficili (anche a causa di una recensione fuorviante).
Ho deciso di rilasciare un nuovo aggiornamento implementando le varie richieste degli utenti. Questa volta ho scelto di promuovere l’applicazione con comunicati stampa su prMac. E non mi sono dimenticato di cambiare la data di rilascio non appena è stata disponibile l’applicazione. Alla fine ho ricevuto un po’ di attenzione dagli utenti americani. Ho raggiunto la posizione 26 sull’AppStore USA nella categoria Fotografia. Intanto avevo conquistato visibilità anche su altri AppStore stranieri. Finora ho venduto 5000 applicazioni in tutto il mondo. Non è il mio primo lavoro (fortunatamente) e sono abbastanza contento.
Ad ogni modo ho ricevuto le mie più grandi soddisfazioni dagli utenti e sono molto più piacevoli dei risultati finanziari. Adesso sono pronto per la versione 1.2 ma nel frattempo mi sto godendo WiFiPhoto tra gli “Staff Picks” sull’AppStore americano ! Apple ti ripaga sempre.

{ 4 comments }

Una veloce introduzione a WiFiPhoto

by admin on 25 settembre 2009

{ 4 comments }

Recensioni fuorvianti

by admin on 20 settembre 2009

Come sviluppatore penso che sia veramente strano il fatto che non possa rispondere alle recensioni dei miei clienti. Soprattutto se asseriscono qualcosa di totalmente sbagliato. Due utenti americani hanno scritto nelle loro recensioni che WiFiPhoto rimpicciolisce le immagini prima del download. Ma è semplicemente falso. WiFiPhoto conserva le dimensioni originali. Quindi se scaricate un’immagine da 1200×1600 pixel con la fotocamera del vostro iPhone 3G, finirete con il trovarvi un’immagine da 1200×1600 pixel sul vostro computer. E allora che succede ?
Semplicemente ignorano il fatto che anche l’immagine originale che hanno scelto di scaricare non era a piena risoluzione. Ci sono vari motivi. Forse hanno usato un’applicazione per scattare foto con lo zoom. O forse, più probabilmente, hanno trasferito album fotografici da iPhoto ai loro iPhone ignorando il fatto che iPhoto riduce e comprime le immagini. Quindi se pensi di poter recuperare le immagini dal tuo iPhone dopo un crash del tuo hard-disk, ho una brutta notizia da darti: non puoi!. O almeno non potrai recuperare le tue immagini a piena risoluzione semplicemente perchè NON SONO sul tuo iPhone.
Mi dispiace ma non potere rispondere a critiche sbagliate è frustrante.

{ 2 comments }

WiFiPhoto

by admin on 5 settembre 2009

ArtworkE’ finalmente disponibile sull’AppStore la mia prima applicazione per iPhone. Nasce da un problema reale con cui mi sono scontrato più volte: il download delle foto su computer che non fossero i miei. A casa uso iPhoto con il mio Mac ma molto spesso mi capita di scattare foto sul lavoro e non ho la possibilità di inviarle sui computer in ufficio. Spedirle via mail è lento e macchinoso. La soluzione ? WiFiPhoto. L’applicazione consente di scegliere più immagini o dal rullino fotografico o dalla libreria e di scaricarle da un qualsiasi computer collegato in rete locale (ovviamente dev’essere un punto di accesso WiFi per iPhone) singolarmente o compresse in un unico file zip. Il tutto è tanto semplice quanto aprire un browser ed impostare l’indirizzo indicato da WiFiPhoto. Niente di più. Maggiori informazioni nella pagina specifica.

{ 9 comments }