RubyCocoa : RequireFramework

Oldest known version of this page was edited on 2008-04-11 10:22:26 by EloyDuran [Added documentation about OSX.require_framework. Thanks to Scott Thompson.]
Page view:
This article discusses the functionality of the RubyCocoa require_framework method. This method allows an application to load a Mac OS X framework and makes that framework's entry points and constants available through the OSX module.

For more information on Frameworks on Mac OS X, please see the Framework Programming Guide

Loading Frameworks with OSX.require_framework


The require_framework method in the OSX module gives RubyCocoa applications a mechanism for loading frameworks into memory and including Ruby entry points for their symbols in that module. From the perspective of the Ruby application, the effect is very similar to that of using a Ruby's include statement to include the instance methods one module into another.

Like the Ruby method Kernel#require, the require_framework method takes a single argument. That argument is a string that defines which framework the routine should import. Fundamentally, the string represents the file system path to the framework you want to load. In typical Ruby fashion, however, there is some flexibility built into the require_framework that makes it easy to bring in common frameworks. Both the fundamental and more convenient mechanisms are worth a further look.

The Fundamental Case


The simplest parameter to require_framework is an absolute file system path to the framework it should load. A common example is presented in Apple's developer documentation in the context of a RubyCocoa application that wants to take advantage of the Scripting Bridge in Mac OS X 10.5 Leopard. In this case, a Ruby application can provide a full path to the operating system's ScriptingBridge.framework. Here is an example:

OSX.require_framework '/System/Library/Frameworks/ScriptingBridge.framework'


After executing this line, if the load is successful, the OSX module will include the classes, functions, and constants of the Scripting Bridge Framework. For example, the OSX module would include the SBApplication class which bridges to the Objective-C class of the same name. The application could continue by creating an instance of SBApplication to communicate with the application of their choice:

safari_app = OSX::SBApplication.applicationWithBundleIdentifier("com.apple.Safari")
safari_app.documents[0].URL = 'http://rubycocoa.sourceforge.net/HomePage'


This same technique could be used to load a custom framework from anywhere within the file system. The RubyCocoa application could use any of a variety of techniques to locate a framework and then load that framework by using its full path.

Built-in Conveniences


Having to supply a full pathname to a framework every time can be inconvenient. Particularly when working with nested frameworks like Apple's umbrella frameworks. Fortunately require_framework also supports some convenient shortcuts for common frameworks. In taking advantage of those shortcuts, an application supplies the name of a framework, and the require_framework method will try to construct a full path to that framework through a set of built-in framework search paths. The method will also recognize some special shortcuts to common frameworks found in the system's umbrella frameworks.

Search Paths

You can pass require_framework the name of a framework without its base directory. In this case, RubyCocoa will search a set of directories looking for a framework with that name and try to load the first instance of the framework that it finds.

Two important paths that RubyCocoa will search are the Frameworks folders in the user and system file system domains (For more information on File System Domains and the Library Directory, please see the File System Overview). Those two directories are:

/System/Library/Frameworks
/Library/Frameworks

A RubyCocoa application can add to these basic search paths by defining the constant RUBYCOCOA_FRAMEWORK_PATHS. If provided, this constant should be an array of additional directories that should be searched when looking for a framework. For example:

RUBYCOCOA_FRAMEWORK_PATHS = ["/Users/scott/MyCustomSoftware/Frameworks"]
OSX.require_framework 'HandyCustomFramework.framework'


Can be used to include a framework at the path:

/Users/scott/MyCustomSoftware/Frameworks/HandyCustomFramework.framework

In addition, if you are running RubyCocoa in an environment where the environment variable HOME is defined, Ruby will also look in a framework and library folder based at that directory. For example, if the value of HOME is /Users/scott then Ruby will also search the directory:

/Users/scott/Library/Frameworks

If the framework to be loaded is in those directories then it is sufficient to simply supply the framework name to require_framework. To return to the first example, Scripting Bridge framework can be included simply with the line:

OSX.require_framework 'ScriptingBridge.framework'


In fact, if you leave off the ".framework" extension, the routine will add it for you. In short, the statement:

OSX.require_framework 'ScriptingBridge'


will work just as well. It is this last form that is most often seen in code samples.

Umbrella Frameworks and Predefined Shortcuts

Mac OS X has the concept of an "Umbrella Framework". An umbrella framework is a Mac OS X framework that contains other frameworks (these contained frameworks are also called subframeworks). In traditional Mac OS X development, an application could link to the umbrella framework in order to import all the functionality of its subframeworks. In fact, it is possible for one umbrella framework to contain subframeworks that are, themselves, umbrella frameworks. One example of an umbrella framework in Leopard is the ApplicationServices framework which contains, among others, the ImageIO, ColorSync, and CoreGraphics frameworks. (for more information on Umbrella Frameworks see the Framework Programming Guide)

When require_framework is asked to import an umbrella framework, it does NOT import the subframeworks. Instead, the subframeworks of an umbrella framework must be loaded explicitly. That means that loading the ImageIO framework is done by a require_framework statement like:

OSX.require_framework '/System/Library/Frameworks/ApplicationServices.framework/Versions/Current/Frameworks/ImageIO.framework'


Long path names like this can be tedious and require_framework includes some convenient shortcuts for popular frameworks. To use a shortcut, you simply pass its name to require_framework. The method will convert the shortcut passed in into the common location for that framework as indicated by the following table:

Shortcut name Framework Path (relative to /System/Library/Frameworks)
CoreGraphics ApplicationServices.framework/Frameworks/CoreGraphics.framework
PDFKit Quartz.framework/Frameworks/PDFKit.framework
QuartzComposer Quartz.framework/Frameworks/QuartzComposer.framework
ImageKit Quartz.framework/Frameworks/ImageKit.framework


Search Order

When using the convenience routines to load frameworks, the order in which the require_framework traverses the search paths and the shortcuts can be significant. require_framework searches for frameworks using the following rules:

  1. If the routine is passed a full path to a framework (and the method assumes that any string passed to it which begins with the directory separator character '/' is a full path to a framework) then require_framework will try to load that framework explicitly.
  2. If one of the shortcuts for the subframeworks listed above is given, then the computer will load the corresponding system framework.
  3. If none of these other criteria is met, the routine searches the framework directory paths in this order:
    1. /System/Library/Frameworks
    2. /Library/Frameworks
    3.  The paths specified by the RUBYCOCOA_FRAMEWORK_PATHS constant, if it is defined
    4.  The path specified by the HOME environment variable, if it is defined

Note: The File System Overview documentation, in the section on Searching Within the File-System Domains recommends searching the domain paths by starting with the user domain, then the local domain, and finally the user domain. require_framework searches these paths in the exact opposite order and inserts the RUBYCOCOA_FRAMEWORK_PATHS in-between the local and user domains.
These rules are applied sequentially to the parameter passed in to require_framework. The routine will only try to load the first framework found when doing that search. If that load fails, the search is aborted and the routine will return an ArgumentError to indicate that the load has failed. Any other frameworks that may have the same name, and which might have been found later in the search, are ignored.

Return Value and Exceptions


If require_framework successfully loads a framework, it returns true. If asked to load a framework that has already been loaded, require_framework will return false. If the routine runs into a problem loading the framework, then it will raise an ArgumentError exception with a message indicating that the framework could not be loaded.
© 2001-2007 The RubyCocoa Project. Powered by Wikka Wakka Wiki 1.1.6.3
SourceForge.net Logo
Page was generated in 0.1816 seconds