Home > iOS, Mobile Development, Objective-C, PhoneGap > PhoneGap Tutorial Series – #6 Writing Your Own Plugin

PhoneGap Tutorial Series – #6 Writing Your Own Plugin

 

How To Create Your Own PhoneGap Plugin

 
Today’s topic is about creating your own PhoneGap plugin for iOS development. PhoneGap provides a whole array of built in features to access all sorts of things on a device but what if you want to do something that is not already supported and has not already been provided by a third-party plugin? Stop fretting, just like adding a third-party plugin, if you can write a little Objective-C then you can add your own plugin to PhoneGap as well.

In order to create your own plugin you will have to be somewhat familiar with JavaScript as well as Objective-C. This tutorial assumes that you are familiar with JavaScript, Objective-C, the iOS SDK, and the XCode development environment. This post also assumes that you are familiar with the PhoneGap project structure and the PhoneGap plugin architecture, so you may want to peruse some of my earlier posts before continuing on if you haven’t already.
 

So…You Need a Plugin to do XYZ … Now What?

The process of creating your own PhoneGap plugin is relatively simple and depending on the complexity of the plugin, takes just minutes. I have provided two examples that have different types of behavior.

1. ActivityIndicatorCommand – The first plugin is very simple and provides a mechanism for showing an activity indicator with a message, updating that message, and hiding the indicator. This plugin could be useful if you are loading a webpage or you have a long running server side post and want to prevent user interaction. This plugin does not use the onSuccess and onFailure method callback pattern since it’s a very simple user interface addition.

2. iPodCommand – The second plugin provides a mechanism to interact with the iPod music library, select a song, and play that song. This plugin does use the OnSuccess and onFailure pattern to notify the JS to show details of the selected song and allow the user to start/pause playing of the song. You must be running on a device for this plugin to work as the simulator does not have an iPod library.

Note: the iPod plugin is a VERY simple implementation and is not meant for production use as it does not take into consideration audio route changes (like plugging in headphones or a phone call coming in etc) among other things. The example is given in order to demonstrate a successCallback for PhoneGap not as a tutorial for how to write an audio streaming application.

See this link for more information on iPod programming.

To get started you need to create several files:

  1. Create a new directory in your ${PROJECT_DIR}/plugins directory (ex: ActivityIndicator)
  2. Create a JavaScript file within that new directory (ex: ActivityIndicator.js)
  3. Create a new Objective-C class that extends the PhoneGapCommand class, also in the new directory (Ex: ActivityIndicatorCommand.h & ActivityIndicatorCommand.m)

Within the newly created JavaScript file:

  1. lines 1-4 – Create a new JavaScript Object class
  2. lines 6-22 – Add methods to the Object prototype to call the PhoneGap.exec() function with a string identifying the corresponding method in your PhoneGapCommand class and pass any needed parameters. Because these methods have been added to the object prototype, they are considered instance methods. Meaning you need to create an instance of the object before you can call these methods.
  3. lines 24-33 – Add a class method to the object to “install” the object at runtime which will instantiate the object and make it accessible via window.plugins
  4. line 35 – Tell PhoneGap about your plugin so that it will be automatically “installed” when PhoneGap initializes itself
function ActivityIndicator()
{

};

ActivityIndicator.prototype.show = function(message)
{
    PhoneGap.exec('ActivityIndicatorCommand.show', message);

};

ActivityIndicator.prototype.updateMessage = function(message)
{
    PhoneGap.exec('ActivityIndicatorCommand.updateMessage', message);
    
};

ActivityIndicator.prototype.hide = function()
{
    PhoneGap.exec('ActivityIndicatorCommand.hide');


};

ActivityIndicator.install = function()
{
    if(!window.plugins)
    {
        window.plugins = {};	
    }

    window.plugins.activityIndicator = new ActivityIndicator();
    return window.plugins.activityIndicator;
};

PhoneGap.addConstructor(ActivityIndicator.install);

Next up, you need to implement your desired methods in your PhoneGapCommand class. In the ActivityIndicatorCommand class I have created methods to hide, show, and update a message on an activity indicator. The class and method names must match exactly the strings that represent the PhoneGap commands that I am calling in my ActivityIndicator.js file.

You will notice that each method defines an array of arguments as well as a dictionary of options. This is a PhoneGap pattern and allows you to pass in as many arguments and options as you like.

//  ActivityIndicatorCommand.m
//  HelloPhoneGap
//  Created by Hiedi Utley on 4/8/11.
//  Copyright 2011 Chariot Solutions, LLC. All rights reserved.
//
#import "ActivityIndicatorCommand.h"
#import "DSActivityView.h"
@implementation ActivityIndicatorCommand
- (void) show:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
{
    NSString * message = [arguments objectAtIndex:0];
    [DSBezelActivityView newActivityViewForView:[[self appViewController] view] withLabel:message];
}
- (void) hide:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
{
    [DSBezelActivityView removeViewAnimated:YES];
}
- (void) updateMessage:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
{
    NSString * message = [arguments objectAtIndex:0];
    [DSBezelActivityView updateMessage:message];
}
@end

Note: the DSActivityView class that I am using to display the activity indicator and message is from a previous post and is based on open source that I have modified to allow the updating of an existing message.
 

Putting it All Together

Once you have created the JavaScript and implemented the Objective-C classes, you then need to add your JavaScript to your HTML page and try it out.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <!-- Change this if you want to allow scaling -->
        <meta name="viewport" content="width=default-width; user-scalable=no" />
        
        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
            <link rel="stylesheet" href="HelloPhoneGap.css" type="text/css"/>
            <title>HelloPhoneGap</title>
            <script type="text/javascript" charset="utf-8" src="phonegap.0.9.4.min.js"></script>
            <script type="text/javascript" charset="utf-8" src="ActivityIndicator.js"></script>
            <script type="text/javascript" charset="utf-8">
                var ai;
                function onBodyLoad()
                {
                    document.addEventListener("deviceready",onDeviceReady,false);
                }
                /* When this function is called, PhoneGap has been initialized and is ready to roll */
                function onDeviceReady()
                {
                    ai = window.plugins.activityIndicator;
                }
                function showActivityIndicator(message)
                {    
                    ai.show(message);
                    window.setTimeout('ai.hide()', 2000);                    
                    
                }
                function showActivityIndicatorUpdateMessage(message)
                {
                    ai.show(message);
                    window.setTimeout('updateMessage()', 2000); 
                    window.setTimeout('ai.hide()', 5000);
                }
                function updateMessage()
                {
                    ai.updateMessage('I am a new message!!!');
                }
                </script>
            </head>
    <body onload="onBodyLoad()">
             <button onclick="showActivityIndicator('I am an activity indicator!')">Show Activity Indicator</button> <br>
             <button onclick="showActivityIndicatorUpdateMessage('I am an activity indicator!')">Show Activity Indicator with Message Update</button>
    </body>
</html>

Where to get the Code?

If you are using PhoneGap 0.9.6

You can get the entire source for my sample project “HelloPhoneGap” from github here: https://github.com/hutley/HelloPhoneGap

If you are using PhoneGap 1.0

You can get the entire source for my sample project “HelloPhoneGap1.0” from github here: https://github.com/hutley/HelloPhoneGap1.0

Well that’s all for now! Go write your first plugin!

Advertisements
  1. June 8, 2011 at 5:51 PM

    Hey Hiedi and thanks for a great set of Tutorials! 🙂

    I’ve been reading some blog posts about phone gap projects and code visibility of apps in the app store. People are basically able to view the apps code very easily by extracting the contents of the apps from itunes. Would writing a plugin for phonegap at least make it harder for people to “steal” your code?

    • June 8, 2011 at 8:48 PM

      Well since typical phonegap projects are written in html and javascript they are relatively easy to crack with a tool like iPhoneExplorer and as such can be “stolen” pretty easily but if you write your own plugin for some stuff it is written natively in Objective-C and compiled into byte code and while I am sure can be decompiled if people get ahold of your symbols files but should be much harder for the average developer….

  2. chepukha
    July 26, 2011 at 11:31 AM

    Thank you Hiedi for this great tutorial. It’s very easy to understand and follow.
    However, I have a question. How can I do to pass an array to the function in javascript file? Let say for example, instead of having ‘message’ as a string variable, I want to have it as an array?
    I tried it with my code and in ActivityIndicatorCommand.m, in the show() function, [arguments count] will not give me the right number of arguments, all the array arguments will be skipped.
    Thanks,

  3. Simon
    August 11, 2011 at 8:39 AM

    This is a very useful tutorial as I was looking for a music player plugin, but I can’t get it to work! It opens the music library but when I select a tune it just freezes. Is there a bug or am I just doing something wrong?

    Thanks,
    Simon.

    • August 15, 2011 at 7:25 PM

      Check the console output – do you see any errors?

      • Simon
        August 19, 2011 at 11:41 AM

        Thanks for the reply. I’ve figured out what was going wrong – I was trying to include the iPod plugin in an existing phonegap project but I hadn’t included all the necessary code in the AppDelegate file. I don’t know Objective-C so it took a bit of trial and error but it’s working now.

        Thanks,
        Simon.

  4. Pat
    August 22, 2011 at 7:04 PM

    Great tutorials. Thanks!
    What about the PhoneGap.plist, isn’t it required to be updated with the plugin objects name?

    I get this error:
    ERROR: Plugin ‘musicPickerCommand’ not found, or is not a PGPlugin. Check your plugin mapping in PhoneGap.plist.

    • August 25, 2011 at 9:29 AM

      As PhoneGap 0.9.6 or so it is necessary to add an entry in the PhoneGap.plist file to map your plugin.

  5. Enrico
    February 21, 2012 at 7:20 AM

    Very usefull plugin!
    Is it possibile center the loaded indicator without
    and delete the animation ?
    Thanks
    Enrico

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: