A LockInfo plugin starts with a plugin controller. A plugin controller is responsible for initializing a plugin and setting the datasource and delegate for the LockInfo table view.
@protocol LIPluginController <NSObject>
-(id) initWithPlugin:(LIPlugin*) plugin;
@end
LIPlugin is an object defined by LockInfo to give the controller access to preferences and other metadata about the plugin.
@interface LIPlugin : NSObject
@property (nonatomic, retain) id<UITableViewDelegate> tableViewDelegate;
@property (nonatomic, retain) id<UITableViewDataSource> tableViewDataSource;
// basic metadata about plugins
- (BOOL) enabled;
- (BOOL) native;
- (NSString*) bundleIdentifier;
- (NSBundle*) bundle;
- (NSBundle*) globalBundle;
- (NSDictionary*) preferences;
- (NSDictionary*) globalPreferences;
- (NSArray*) managedBundles;
// API calls for previews
-(UIView*) showPreview:(UIView*) content;
-(void) dismissPreview;
@end
During initialization, the plugin controller needs to register the table view delegate and data source that LockInfo should use to load data and handle callbacks for the LockInfo table view. The delegate and data source should follow the same rules as any standard iPhone SDK table view.
Notifications
At init time, the plugin controller should also register for notifications that it cares about.
// update with...
static NSString* LIUpdateViewNotification = @"com.ashman.LockInfo.updateView";
// respond to...
static NSString* LIUndimScreenNotification = @"com.ashman.LockInfo.screenUndimmed";
static NSString* LITimerNotification = @"com.ashman.LockInfo.timerFired";
static NSString* LIViewReadyNotification = @"com.ashman.LockInfo.viewReady";
static NSString* LIPrefsUpdatedNotification = @".prefsUpdated";
static NSString* LIBadgeChangedNotification = @".badgeChanged";
static NSString* LIApplicationDeactivatedNotification = @".applicationDeactivated";
There are two different types of notifications listed above. You’ll notice that some are fully-qualified notification names and some are just the last part of a notification name. The difference lies in whether the notification is generic for LockInfo or app/plugin specific. For example, all plugins can respond to the generic “undim screen” notification with LIUndimScreenNotification. Additionally, a particular plugin could respond to an application closing with LIApplicationDeactivatedNotification, where the notification is prefixed with the bundle identifier of the application that closed.
-(id) initWithPlugin:(LIPlugin*) plugin
{
self = [super init];
self.plugin = plugin;
self.dataCache = [NSMutableDictionary dictionaryWithCapacity:10];
self.iconCache = [NSMutableDictionary dictionaryWithCapacity:10];
self.daysView = [[[WIForecastDaysView alloc] init] autorelease];
self.iconView = [[[WIForecastIconView alloc] init] autorelease];
self.tempView = [[[WIForecastTempView alloc] init] autorelease];
plugin.tableViewDataSource = self;
plugin.tableViewDelegate = self;
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(update:) name:LIViewReadyNotification object:nil];
[center addObserver:self selector:@selector(updateOnUpdate:) name:@"WIWeatherUpdatedNotification" object:nil];
[center addObserver:self selector:@selector(refreshWeather:) name:[plugin.bundleIdentifier stringByAppendingString:LIBadgeChangedNotification] object:nil];
return self;
}
LIUpdateViewNotification is a notification that goes the opposite direction. Plugin controllers should post this notification, with the plugin as the object, to the default notification center. This will trigger LockInfo to update the view with updated data. The notification can include data in the userInfo which will be sent to an HTML theme if you wish to support HTML themes (more on this later).
-(void) updateWeather:(NSDictionary*) weather
{
if (!self.plugin.enabled)
return;
// Do some stuff to load the weather...
...
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:weather, @"weather", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:LIUpdateViewNotification object:self.plugin userInfo:dict];
}
TableView DataSource/Delegate
@protocol LITableViewDataSource <UITableViewDataSource>
@optional
// Custom datasource methods for showing the correct counts on the screen.
-(NSInteger) tableView:(LITableView*)tableView numberOfItemsInSection:(NSInteger)section;
-(NSInteger) tableView:(LITableView*)tableView totalNumberOfItemsInSection:(NSInteger)section;
// Custom method for manual refreshes
-(void) tableView:(LITableView*)tableView reloadDataInSection:(NSInteger)section;
@end
@protocol LITableViewDelegate <UITableViewDelegate>
@optional
// Custom methods for getting the icon and detail for the headers of the sections.
-(NSString*) tableView:(LITableView*) tableView detailForHeaderInSection:(NSInteger) section;
-(UIImageView*) tableView:(LITableView*) tableView iconForHeaderInSection:(NSInteger) section;
// Method for creating a preview
-(UIView*) tableView:(LITableView*) tableView previewWithFrame:(CGRect) rect forRowAtIndexPath:(NSIndexPath*) indexPath;
@end