Q: How can I make my NSCollectionView items selectable? In awakeFromNib I have:
[projectArrayController addObserver:self
                    forKeyPath:@"selectionIndexes"
                       options:NSKeyValueObservingOptionNew
                       context:nil];

and I have:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                        change:(NSDictionary *)change context:(void *)context {
    NSLog(@"%@ forObject: %@",keyPath, object);
    if([keyPath isEqualTo:@"selectionIndexes"]){
        NSUInteger numberOfSelected = [[projectArrayController selectedObjects] count];
        if(numberOfSelected >0){
            if (numberOfSelected == 1){
                ProjectModel *pm =  (ProjectModel *)[[projectArrayController selectedObjects] objectAtIndex:0];
                [pm setSelected:YES];
            }
        }
    }
}

which logs: selectionIndexes forObject: <NSArrayController: 0x1001cb6e0>[object class: ProjectModel, number of selected objects: 1]
But I can't actually click on anything else when I run my program. Why is this?
What type of delegate should I use? I tried using a tableview delegate and collectionview delegate so far.
Or alternatively, How can I make my NSCollectionView the first responder?

A: I got this working but it's not easy. You have to subclass your collection view's subview which is a subclass of NSView. Here's what my subclass looks like...
@implementation GiggleCollectionSubView
@synthesize itIsSelected;

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        itIsSelected = NO;
    }
    return self;
}

- (void)dealloc {
    [super dealloc];
}

- (void)awakeFromNib {

}

- (void)drawRect:(NSRect)rect {
    [[NSColor clearColor] set];
    if (self.itIsSelected) {
        [NSGraphicsContext saveGraphicsState];
        NSSetFocusRingStyle(NSFocusRingAbove);
        [[NSBezierPath bezierPathWithRect:NSInsetRect([self bounds], 2, 2)] fill];
        [NSGraphicsContext restoreGraphicsState];
    } else {
        [[NSBezierPath bezierPathWithRect:[self bounds]] fill];
    }
}

- (void)mouseDown:(NSEvent *)theEvent {
    if ([theEvent clickCount]==1) {
        if (![self itIsSelected]) {
            [[[NSApp delegate] giggleWindowController] clearCollectionView];
            [self setItIsSelected:YES];
            [self setNeedsDisplay:YES];
            [[[NSApp delegate] giggleWindowController] updateSelectionIndexes];
            [[[NSApp delegate] giggleWindowController] showSelectedImage];
        }
    }
}

@end

So you can see I have an instance variable called itIsSelected. This is the key. I manually manage that variable which makes everything work. First in the drawRect method it determines if the subview has a focus ring drawn to indicate that a subview is selected. Next in the mouseDown: method is where I detect when a user clicks on a subview to select it. In there I manually manage the selectionIndexes of the array controller and manually manage the itIsSelected instance variables of all the subviews. So first I set itIsSelected to NO for all the subviews in the method clearCollectionView. Next I set itIsSelected to YES for the clicked subview. I then update the selectionIndexes of the array controller and then do something based on the selectedObject (e.g. in showSelectedImage). Here's those 2 methods.
-(void)clearCollectionView {
    NSArray* cvViews = [artistImagesCV subviews];
    for (GiggleCollectionSubView* aView in cvViews) {
        if ([aView itIsSelected]) {
            [aView setItIsSelected:NO];
            [aView setNeedsDisplay:YES];
        }
    }
}

-(void)updateSelectionIndexes {
    NSArray* cvViews = [artistImagesCV subviews];
    NSMutableIndexSet* indexes = [NSMutableIndexSet indexSet];

    NSUInteger counter = 0;
    for (GiggleCollectionSubView* aView in cvViews) {
        if ([aView itIsSelected]) [indexes addIndex:counter];
        counter++;
    }
    [googleImagesArrayController setSelectionIndexes:(NSIndexSet*)indexes];
}

NOTE: in my subview I also have an image view. I had to subclass that and do similar in its mouseDown method.
Anyway, I hope this helps. I couldn't get it working using the method you were trying so I did it manually as explained. Good luck.
