The RAMP iOS template project for Xcode can be downloaded here.
All the resources required to build an iOS plugin are provided as an Objective-C framework. The framework, rampvm.framework, is available here.
It is explained in the iPhone Building Guide that an iPhone RAMP app cannot be deployed through the usual channels. This is also true for developing a plugin and implementing it in an iPhone RAMP app.
The plugin process is more or less similar to the explanation in the RAMP VM Plugins document. The big difference is that the RAMP Deployment platform is not involved and its role has to be performed manually. This guide references the RAMP VM Plugins document and assumes you are familiar with it.
Writing a Plugin
Note the classes that need to be extended and implemented are now provided in Objective-C and look slightly different to their Java versions.
Writing a function plugin
The differences in Objective-C's version of class APluginFunction:
- Instead of two possible constructors, there are now two possible initialization methods:
initWithNamethat takes a single string and
initWithNamesthat takes an array of strings.
- The invoke method now also takes a NSError object as an extra, third parameter.
- An added, useful method is
currentViewControllerthat retrieves the ViewController that is currently active in the RAMP app. Launching a new ViewController from a plugin requires access to the currently active one.
The APluginFunction's header file is given below:
All the resources required to build an iPhone plugin are provided as an Objective-C framework. The framework, rampvm.framework, is available here.
An iPhone example is given with the code below. It is the iPhone version of the SMS Plugin example. This plugin provides the RAMP-script function
Note the following in the example code:
- Registering the function name in the
isSupportedmethod checking if the plugin is supported on the device.
- The use of
currentViewControllermethod to launch and dismiss a new viewController.
Writing a UI Component plugin
The interface (protocol) class APluginUi is basically identical to its Java version.
Including Plugins in an App
To include one or more plugins in an app,
- the plugins must be included in the RAMP iPhone template project that will build the app and
- the VM must be aware of the plugins' existence.
A plugin can either be included as source code or in a compiled form. The template project contains a
plugins directory in its root with sub-directories
resources specially created for keeping plugins. The template project is configured to search the plugins'
headers directory for header files. Libraries and other resource files (e.g. images) must be included manually using Xcode in the target named "vmt" (there is only one target).
The rampvm.framework framework is already included in the template project.
plugins.txt is provided in the root of the template project to inform the VM of the plugins' existence. For all the plugins that you wish to include in an app, the name of the plugin's class (i.e. the class that extends class APluginFunction) must be included in
plugins.txt. The names must be listed vertically in
Plugins.txt, one below the other. The following is the
plugins.txt file for the guide's function plugin example.
Using a Plugin's Function in an App
UI Component plugins require no further configuration to use.
The final hurdle is persuading the RAMP IDE to allow the use of a function plugin's function. This is typically achieved with the "Get RAMP VM plugins..." option in the IDE, but without the development platform's involvement it has to be done manually.
In the root directory of a RAMP project (not the RAMP VM template project) there is a file
.plugins. This file is typically hidden in most operating systems and can be created if it does not exist. This file contains a list of all the plugin functions that a project allows. The function names appear as they are to be used in the IDE, but without any reference to their parameters. The names are listed one below the other (similar to
plugins.txt). This file should be edited and all required plugin functions included. The following is the
.plugins file for the guide's function plugin example:
If new plugin functions are not recognized after editing
.plugins, restart Eclipse.
Appendix I - Standard PluginUtils methods on iOS
(void) executeAction: (NSString*) action
Execute a RAMP action where an action is either
- a RAMP function
- or going to a ramp form.
An example of a RAMP function:
is equivalent to RAMP code
An example of going to a RAMP form:
equivalent to RAMP code
(void) executeFunction: (NSString*) function withArgs: (NSArray*) args
Execute a RAMP function, e.g.
is equivalent to RAMP code
(NSString*) getTrimmedKey: (NSString*) key node: (id<IDotNode>) node
Given a node and key, it returns the key trimmed (truncated) to everything after the node's ID. Used when developing UI components.
(id) getValueFromUxmlChildren: (NSArray*) nodes parent: (id<IDotNode>) parent key: (NSString*) key
For parent component with an array of nodes as its children, returns the value for the first IDotNode instance in nodes that supports the given key.
(BOOL) setValue: (id) value forKey: (NSString*) key inUxmlChildren: (NSArray*) nodes parent: (id<IDotNode>) parent
For parent component with an array of nodes as its children, set the value for the first IDotNode instance in nodes that supports the given key. Returns true if successful.
(NSMutableArray*) unmarshall:(NSArray*)marshalled unmarshalled:(NSMutableArray*)unmarshalled
Unmarshalls an array of marshalled (raw) UXML components.
(NSMutableDictionary*) marshall:(id <IDotNode>)node attributes:(NSArray*) attributes
Marshall (convert to raw type) a UXML node that support all the keys listed in the attributes parameter.
(NSMutableArray*) marshallChildren:(NSArray*) childNodes
Marshall (convert to a list of raw types) a vector of UXML nodes.
(UxmlStyle*) getUxmlStyle: (NSString*) styleName
Retrieve the UXML style object that has ID styleName.
Appendix II - PluginUtils methods unique to iOS.
(void) executeAction: (NSString*) action viaUxmlComponent:(id <IDotNode>)srcComponent
execute a RAMP action and inform the VM that a specific IDotNode UI component triggered the action.
Returns the display size of the device.
Returns the device's orientation
(Image*) getImage: (NSString*) imageName
Returns the Image object for the Uxml Image Component that has ID imageName.
Returns the currently displayed VM UIViewController.
(void) setCurrentViewController:(UIViewController*) viewController
Set the currently displayed VM UIViewController. Only for testing purposes.
Returns true if device has a retina display.
Returns true if device is an iPad
(BOOL) isIosVersionGreaterOrEqual:(NSString*) version
Returns true if device's iOS version is greater or equal to the version parameter.
(void) displayFatalError: (NSString*) message
Go to the RAMP VM's fatal error page and display the message parameter.
(void) runOnUIThread:(void ( ^ )())block
Run a block on the UI thread.
(void) runOnBackgroundThread:(void ( ^ )())block
Run a block on a backgroud (non-UI) thread.
(void) runBlock:(void (^)())block
Run a block.
(NSNumber*) parseNumber:(NSString*)value error:(NSError**) error
Convert RAMP's string value to a Objective-C NSNumber.
(NSNumber*) parseNumber:(NSString*)value isFloat:(BOOL*)isFloat error:(NSError**) error
Convert RAMP's string value to a Objective-C NSNumber and detect if number is a float.
(UIColor*) getUIColorWithDescriptor:(long long) d
Convert a long representation of a color to a UIColor object.