An NSURL Category For Adding to Favorites Lists

I encountered a question on StackOverflow today about how to add items to the favorites list in the Finder sidebar (which also appears in the standard Open and Save dialogs’ side bars). Though it’s already been answered before (I marked it as a duplicate, pointing to an answer from 2011), it appears the information is a bit outdated and contained no example code. I wrote, tested, and added the code to an updated answer. Not satisfied to stop there, I felt it would be easier to use if I created a simple category on NSURL so you could tell a valid file URL directly to add itself to either the favorite items or favorite volumes list with one call. It’s compatible back to 10.5.

I wanted the design and usage to be simple, so I made a few drastic decisions:

  1. Due to some Finder bugs, you could set either a custom icon or a custom title for an item, but not both at the same time. Since the default behavior is to use the default icon and file name (sans extension, if one exists), I simply don’t provide the option to customize the icon or name.
  2. Though there’s an option to specify adding an item to the end, or to the beginning, or even to resolve each item and specify an item after which to add your own, this complicates matters, so I opted for append only. Your users may not appreciate you putting your item at the top of their lists anyway. Back of the line, new guy. 😉
  3. The call either succeeds or fails. No complicated error messages, no nothing.
  4. Any valid file URL can be added by calling either [url appendToFavoriteItemsList]; or [url appendToFavoriteVolumesList]; and checking the BOOL return value if you care.

The code:

//
// NSURL+FavoritesList.h
// FavoritesListTester
//
// Appends the URL to the end of the Favorite Items or Favorite Volumes list
// (found in the side bar of Finder windows and open/save dialogs, etc.)
//
// Notes:
//
// 1. Must be a file URL.
// 2. Appends only (no insert at top for simplicity).
// 3. Compatible back to Mac OS X 10.5.
// 4. Due to Finder bugs over the years, this category doesn't bother
// allowing for setting custom icons/names; it just uses the default Finder
// icon and file name for simplicity.
//
// Created by Joshua Nozzi on 6/23/15.
// https://joshua.nozzi.name/2015/06/23/nsurl-category/
// https://gist.github.com/jnozzi/817f3276c55dbb7025be
//
// Copyright (c) 2015 Joshua Nozzi. All rights reserved.
// Released under BSD license (this notice must be retained if redistributed).
// No guarantees made. Use at your own risk.
//
#import <Foundation/Foundation.h>
@interface NSURL (FavoritesList)
– (BOOL)appendToFavoriteItemsList;
– (BOOL)appendToFavoriteVolumesList;
@end
//
// NSURL+FavoritesList.m
//
// Appends the URL to the end of the Favorite Items or Favorite Volumes list
// (found in the side bar of Finder windows and open/save dialogs, etc.)
//
// Notes:
//
// 1. Must be a file URL.
// 2. Appends only (no insert at top for simplicity).
// 3. Compatible back to Mac OS X 10.5.
// 4. Due to Finder bugs over the years, this category doesn't bother
// allowing for setting custom icons/names; it just uses the default Finder
// icon and file name for simplicity.
//
// Created by Joshua Nozzi on 6/23/15.
// https://joshua.nozzi.name/2015/06/23/nsurl-category/
// https://gist.github.com/jnozzi/817f3276c55dbb7025be
//
// Copyright (c) 2015 Joshua Nozzi. All rights reserved.
// Released under BSD license (this notice must be retained if redistributed).
// No guarantees made. Use at your own risk.
//
#import "NSURL+FavoritesList.h"
@implementation NSURL (FavoritesList)
– (BOOL)appendToFavoriteItemsList {
return [self appendToList:kLSSharedFileListFavoriteItems];
}
– (BOOL)appendToFavoriteVolumesList {
return [self appendToList:kLSSharedFileListFavoriteVolumes];
}
– (BOOL)appendToList:(CFStringRef)list {
// Pessimism …
BOOL result = NO;
// Do we have a file URL?
if (self.isFileURL) {
// Ask CoreServices for the favorite items list
LSSharedFileListRef listRef = LSSharedFileListCreate(NULL, list, NULL);
if (listRef) {
// We've got the list, so try to append our item
LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(listRef,
kLSSharedFileListItemLast,
NULL,
NULL,
(__bridge CFURLRef)self,
NULL,
NULL);
// Did it work?
if (itemRef) {
// Release the item and flag success
CFRelease(itemRef);
result = YES;
}
// Release the list
CFRelease(listRef);
}
}
return result;
}
@end

Usage:

#import "NSURL+FavoritesList.h
NSString * itemPath = [@"~/Music" stringByExpandingTildeInPath];
NSURL * itemURL = [NSURL fileURLWithPath:itemPath];
[itemURL appendToFavoriteItemsList];

I hope you find it useful!