Creating a Widget Plug-in
Widgets alone cannot access applications directly, receive distributed notifications, or read files from disk. To enable these interactions, you need to provide a plug-in. You are required to implement an interface for your plug-in that makes itself available to the widget. This interface communicates with your application in whatever manner is most appropriate, for example, by issuing AppleScript commands.
For example, if you wanted to display an Address Book contact image in your widget, you would create a plug-in to access the image, write it to a temporary file, and set the file as the
src value. (Note that if the temporary file is outside the widget’s bundle, you would also need to specify the
AllowFileAccessOutsideOfWidget key, as described in “Using Access Keys.”) Another example is if you wanted to use a widget as another way to provide an interface to an application. Providing a widget front end allows a user to interact with your application in an unobtrusive and simple way that is easily accessible.
A widget plug-in is a Cocoa bundle. In Xcode, use the "Cocoa Bundle" template to create a bundle. In the plug-in code, implement the widget plug-in interface.
For examples of widgets that use plug-ins, see Birthdays and Reminders sample code projects.
Widget Plug-in Interface
Any widget plug-in must implement this method in order to be used from within Dashboard:
- (id) initWithWebView:(WebView*)webview
Dashboard calls this when your plug-in is first loaded. At this point, initialize an object of your principal class and prepare any critical data structures.
WebScripting. In addition to this interface, you also need to implement this method:
- (void) windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject
setValue: forKey: on the just-received
WebScriptObject to bind it to your own object and to give it a name. In order to function properly, the object that you bind to the
WebScriptObject must implement the WebScripting interface.
This example demonstrates what your implementation of this method should include:
- (void) windowScriptObjectAvailable:(WebScriptObject *) windowScriptObject
[windowScriptObject setValue:self forKey:@"MyWindowScriptObject"];
Any methods that belong to the object that you bind to the given
+ (NSString *)webScriptNameForSelector:(SEL)aSelector
In the following example, your plug-in class is bound to a received
windowScriptObject. The key for the object is
MyWindowScriptObject, meaning that, from within the widget, any method belonging to the
MyWindowScriptObject class may be called upon it:
For example, you can use this to notify the plug-in when the widget is finished loading in Dashboard. You can set up a function to be called when the widget has finished loading. This function will, in turn, call any method you supply:
Widget Plug-in Bundle
The Xcode standard information property list file provides most of the information you need for the plug-in to function properly. Despite this, you must provide a value for the
Once you compile the bundle, you are ready to deploy it. For your widget to use your plugin, place it at the root level of your widget bundle.
In order for your plug-in to be loaded when you activate your widget, it needs to be specified in your widget’s
Info.plist file. The property
Plugin needs to be added, and its value should be a String filled with the name of your bundle.
For more information on Dashboard plug-ins, see Dashboard Reference in Apple Applications Documentation.
When compiling your widget plug-in, make sure you're building it as a Universal plug-in for use on PowerPC and Intel-based Macintosh computers. For more on Universal binaries, read Technical Q&A QA1451: Intel-Based Macs, Dashboard, Safari, and You and Universal Binary Programming Guidelines, Second Edition.