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 days on sale

by admin on 13 October 2009

US-AppStore-Staff-PicksWiFiPhoto has been on sale for 40 days now. Some frustrations, many satisfactions. In the beginning I didn’t know what to expect. Just after its release I discovered I had made a terrible mistake. When you submit an application to Apple you decide the release date. I chose to leave the submission date, 22nd August. WiFiPhoto went on sale on 4th September. I didn’t know I could change my release date: my app was buried amidst tons of other apps and it didn’t get any benefit from being just released. A hard lesson that I’ve definitely learned. I sent a quick press release to Macity one of the most popular Mac and iPhone related websites in Italy (perhaps the MOST popular. take a look at Alexa). My sales readily took off. In a week I had sold over 2,000 apps only in Italy. Japanese friends also gave me satisfaction: some bloggers made a good review and it helped a lot. Indeed I was primarily interested in USA but at first things were very difficult (even because of a misleading customer’s review).
I decided to release a new update implementing various features I was requested. This time I chose to promote my app via a PR on prMac. And I didn’t forget to change my release date as soon as it became available on the AppStore. Eventually I got some attention from american users. I reached #26 in US AppStore in Photography category. In the meantime I had conquered some visibility even on other foreign AppStores. By now I’ve sold more than 5,000 apps all around the world. That’s not my first job (luckily) and I’m quite happy.
Anyway I received my greatest satisfactions from customers and they’re by far more pleasant than any financial result. Now I’m ready for version 1.2 but in the meantime I’m enjoying WiFiPhoto among “Staff Picks” on US AppStore ! Apple always rewards you.

{ 4 comments }

A quick introduction to WiFiPhoto

by admin on 25 September 2009

{ 4 comments }

Misleading customer reviews

by admin on 20 September 2009

As a developer I think it’s really weird the fact that I can’t answer to customers’ reviews. Especially if they claim something totally wrong. Two users from USA wrote in their reviews that WiFiPhoto scales down images before download. But it’s simply false. WiFiPhoto keeps photos at their original dimensions. So if you’re downloading a 1200×1600 pixel picture taken by your iPhone 3G’s camera, you’ll end up finding a 1200×1600 pixel picture on your computer. So, what’s happening ?
They simply ignore the fact that even the original photo they chose to download was not full resolution. There are different reasons. Perhaps they used some third-party camera app to take pictures with a zoom. Or perhaps, more probably, they transferred photo albums from iPhoto to their iPhones ignoring the fact the iPhoto shrinks and compresses images. So if you think to recover images from your iPhone after a crash of your hard drive, I have some bad news for you: you can’t. Or at least you won’t be able to recover your full resolution original pictures, simply because they’re NOT on your iPhone.
I’m sorry for this, but being unable to answer wrong customers’ complaints is frustrating.

{ 2 comments }

WiFiPhoto

by admin on 5 September 2009

ArtworkAt last my first iPhone application is available on the AppStore. It was thought as a solution to my worst problem with iPhone: how to download photos to computers without a usb cable. iPhoto is my first choice when I’m home on my Mac but I very often take shots for work and I can’t download them at the office. Sending in emails is complicated and sluggish. My solution ? WiFiPhoto. This app lets you pick multiple photos from the Camera Roll or from the Photo Library and lets you download them to any computer over a local network (there must be a WiFi connection for the iPhone anyway) one at a time or altogether compressed in a zipped file. It’s as easy as opening on your favourite browser the web address displayed by WiFiPhoto. Nothing more. More info at the product page.

{ 9 comments }