BSPluginLoader
Language: Objective-C, Author: Karsten
License: Public domain
BSPluginLoader is a loadable bundle that allows applications to easily load plugins. The plugins can be installed in any applications support folder or in the application's bundle itself.
BSPluginLoader source preview
// // BSPluginLoader.m // BSPluginLoader // // Created by Karsten Kusche on 30.03.07. // /* todos: - move stuff to instance side - make loader more customizable (execute method with object) */ #import "BSPluginLoader.h" @implementation BSPluginLoader - (NSArray*)domainPathes { // domain pathes are used as a basis for searching for plugins. // appending subfolders like 'plugins' to them should list all folders that are used to store plugins. static NSMutableArray* domains; if (domains) { return domains; } domains = [[NSMutableArray alloc] init]; //get the processes name, it's used as subfolder in the app-support folders NSString* appName = [[NSProcessInfo processInfo] processName]; NSEnumerator* basicDomains = [[NSArray arrayWithObjects: @"~/Library/Application Support/", @"/Library/Application Support/", @"/System/Library/Application Support/", nil] objectEnumerator]; NSString* domain; while (domain = [basicDomains nextObject]) { [domains addObject:[[domain stringByExpandingTildeInPath] stringByAppendingPathComponent:appName]]; } // finally add the bundle's contents folder [domains addObject:[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"Contents"]]; return domains; } - (void)initBundle:(NSBundle*)bundle { Class class = [bundle principalClass]; // NSLog(@"principal class for bundle:%@ is: %@",[[bundle bundlePath] lastPathComponent],[class description]); if (class) { if (selector) { if (sender) { [sender performSelector:selector withObject: class]; } } } } - (int)loadPluginsInDomain:(NSString*)domain atPath:(NSString*)aPath withExtensions: (NSArray*)extensions { int bundleCount = 0; NSString* pluginFolder = [[domain stringByExpandingTildeInPath] stringByAppendingPathComponent:aPath]; NSArray* pluginFiles = [[NSFileManager defaultManager] directoryContentsAtPath:pluginFolder]; // if folder doesn't exist, return if (pluginFiles == nil) return 0; NSEnumerator* plugins = [pluginFiles objectEnumerator]; NSString* plugin; while (plugin = [plugins nextObject]) { // check if plugin extension is exqual to the required extension if ([extensions containsObject:[plugin pathExtension]]) { // load bundle NSBundle* pluginBundle = [NSBundle bundleWithPath:[pluginFolder stringByAppendingPathComponent:plugin]]; if ([pluginBundle load]) { //load was successful, increment the counter and init the bundle bundleCount ++; [self initBundle: pluginBundle]; } } } return bundleCount; } - (int)loadPluginsAtPath:(NSString*)aPath withExtension: (NSString*)extension { return [self loadPluginsAtPath:aPath withExtensions:[NSArray arrayWithObject:extension]]; } - (int)loadPluginsAtPath:(NSString*)aPath withExtensions: (NSArray*)extensions { int bundleCount = 0; NSEnumerator* domains = [[self domainPathes] objectEnumerator]; NSString* domain; while (domain = [domains nextObject]) { bundleCount += [self loadPluginsInDomain: domain atPath: aPath withExtensions: extensions]; } // return how many bundles loaded successfully return bundleCount; } + (int)loadPluginsAtPath:(NSString*)aPath withExtension: (NSString*)extension { return [self loadPluginsAtPath:aPath withExtensions:[NSArray arrayWithObject:extension]]; } + (int)loadPluginsAtPath:(NSString*)aPath withExtensions: (NSArray*)extensions { BSPluginLoader* loader = [[self alloc] init]; int bundleCount = [loader loadPluginsAtPath:aPath withExtensions:extensions]; [loader release]; return bundleCount; } - (id) init { self = [super init]; if (self != nil) { selector = nil; sender = nil; } return self; } - (void)setSelector:(SEL)newSelector { selector = newSelector; } - (void)setSender:(id)newsender { [sender release]; sender = [newsender retain]; } - (void) dealloc { [sender release]; [super dealloc]; } + (id)loaderForSender:(id)sender notifyingWith:(SEL)selector { BSPluginLoader* loader = [[self alloc] init]; [loader setSender:sender]; [loader setSelector:selector]; return loader; } @end
BSPluginLoader header preview
// // BSPluginLoader.h // BSPluginLoader // // Created by Karsten Kusche on 30.03.07. // #import <Cocoa/Cocoa.h> /* BSPluginLoader will load all plugins into your application that have a given extension and are located in a given subpath. it will search all domains (~/Library/Application Support /Library/Application Support /System/Library/Application Support) as well as the application-bundle's contents folder. load the bundle by hand when your application launches and benefit of a simplified plugin loading mechanism. */ @interface BSPluginLoader : NSObject { SEL selector; // selector...has to accept the class that was loaded as argument id sender; // target that receives this selector } // create a new loader with sender and action + (id)loaderForSender:(id)sender notifyingWith:(SEL)selector; // load plugins at a relative path (@"plugins" for example) and with a given extension, or extensions + (int)loadPluginsAtPath:(NSString*)aPath withExtension: (NSString*)extension; + (int)loadPluginsAtPath:(NSString*)aPath withExtensions: (NSArray*)extensions; // same as the class methods, but notifying the target with the selector specified in the factory method - (int)loadPluginsAtPath:(NSString*)aPath withExtension: (NSString*)extension; - (int)loadPluginsAtPath:(NSString*)aPath withExtensions: (NSArray*)extensions; // set the instance variables - (void)setSelector:(SEL)newSelector; - (void)setSender:(id)newSender; @endDownload Archive
Compatible with:
- Mac OS X 10.3
- Mac OS X 10.4 PPC
- Mac OS X 10.4 Intel
- Mac OS X 10.5 PPC
- Mac OS X 10.5 Intel

You should not hard-core any path. This is a bad practice. Use NSSearchPathForDirectoriesInDomains to locate the Application Support folders, and -[NSBundle builtInPlugInsPath] for the internal path.