PhoneGap UIControls ready to go

I’ve merged the results of my UIControls branch on github into my master branch. I think my little experiment went well, and I’d love to get feedback from people on how this new API works for you. I still have some great plans for it, but before I get ahead of myself, let me cover what I’ve done:

Changes:
• Refactored the command call API to allow for a richer set of arguments to PhoneGap commands
• Moved some commands around to more appropriate classes (e.g. Alert and Vibrate both moved to Notifications)
• Reorganized the XCode project so commands are clearly separated from PhoneGap infrastructure
• Renamed the Settings.plist PhoneGap config file to PhoneGap.plist, and created a new Settings.plist file that contains custom application-specific configuration.
• Made all PhoneGap commands inherit from a common base-class that auto-loads its own Dictionary of configuration from the main PhoneGap.plist file.
• Added UIControls command class that exposes tab bars and toolbars to JavaScript.
• Updated the demo to show off tabs and toolbars

All that looks like a big change, but almost all of it was infrastructure changes that were necessary to get UIControls to work. Previously, all PhoneGap commands were class method calls, meaning it was very difficult to maintain state between command calls. Now that commands are actually called on an instance of a given command class, it’s easier to maintain state. So when a tab bar is created, multiple calls can be made, each to construct different aspects of the UI. Without all this, the following example would have been much more complicated:

uicontrols.createTabBarItem(“toprated”, “Top Rated”, “tabButton:TopRated”);
uicontrols.createTabBarItem(“recents”, “Recents”, “tabButton:Recents”);
uicontrols.createTabBarItem(“more”, “More”, “tabButton:More”);
uicontrols.showTabBar();
uicontrols.showTabBarItems(“toprated”, “recents”, “history”, “more”);

The changes to the PhoneGap configuration were necessary because now, when a PhoneGapCommand subclass is constructed, it will look in the PhoneGap.plist configuration file to see if there’s anything pertaining to it. So if there’s a key in the dictionary with the same name as the class being constructed, it will use that as a local configuration dictionary influencing just that one class. That way, if you don’t use a feature of PhoneGap, or you have to configure a lot of options for a single type of command, these options won’t be cluttered alongside the standard global PhoneGap settings.

I created Settings.plist because of experiences I had in an application I’ve been creating in order to test my new UIControls branch changes. I found that I wanted to set compile-time options (for instance a “lite_mode” boolean) that influenced the way my app runs, without having to change HTML or JavaScript code every time. So instead what I have is a configuration plist file that is used exclusively in JavaScript for my application. I’ve added the excellent SB-JSON framework in to the PhoneGap project, and use that to pass these settings into the JavaScript application at start-up time. So all you have to do is read Settings.lite_mode, for instance, in order to read properties set in your plist file.

Oh, and finally, I’ve moved the JavaScript documentation to javascript/docs, since they were practically impossible for new users to find in the past. I’ve been working on creating DoxyGen docs of the PhoneGap code for use in XCode’s documentation browser, but I haven’t gotten far enough there to actually check anything in besides comments. I found instructions on how to generate XCode docsets from DoxyGen, but I haven’t gotten it working just yet.

So please, try out my PhoneGap updates and let me know what you think of it. I think the integration of the JSON framework will make things like Contacts much simpler to implement.

Before I go though, I want to give a little “wish list” of features I’m planning on adding in the near future. I’ll get to them whenever I can, since my own app development takes priority of course.

• Toolbar buttons
• Tabbar show/hide animations
• File support (read / write local files)
• Camera and photo library support (POST to a server, save to a local file, etc)
• Native “Flip / Slide” transitions (no more having to mimic them in CSS)
• 3rd party API integration, like AdMob and Medialets (I already have both of these done, but I’m in discussions with both companies to determine if the terms of their license allows me to redistribute it)

Tags:

About Michael Nachbaur

iOS app developer, livin' the dream. Working from wherever I find myself; Hawaii, Santa Monica, Vancouver, and elsewhere.

24 Responses to “PhoneGap UIControls ready to go”

  1. Roberto Saccon April 24, 2009 11:29 am
    #

    Great stuff you are doing !

    Just checked cloned you repo, tried to build, but it failed:

    http://pastebin.mozilla.org/644218

    (If I remember properly, I checked out before the normal phonegap and it just built without problems)

  2. Mike Nachbaur April 24, 2009 12:25 pm
    #

    Ah yes, it looks like the course / speed features are only supported in iPhone OS 2.2 and above. I’ve put in a conditional block there to only supply course / speed when it’s available to your current platform.

    Pull down from github again, and try again please.

  3. bradheintz April 24, 2009 12:44 pm
    #

    All of this sounds cool. Is there any documentation? Has the iPhone walkthrough on the wiki been updated?

  4. Lokkju April 24, 2009 2:38 pm
    #

    Looks like there is a problem in the ${SRCROOT} var – it doesn’t handle spaces.

  5. Mike Nachbaur April 24, 2009 3:28 pm
    #

    Lokkju: Ah good catch. I’ve pushed out an update for this, though it’s a very simple patch.

    bradheintz: Yes, there’s JavaScript documentation in javascript/docs of the API, and there’s the beginnings of Objective-C level documentation in the UIControls.m file. I’ll be updating the wiki when time presents itself, though if someone out there wants to step up to the plate and start it for me I’d greatly appreciate it. It may be some time before I can get around to it.

  6. J. Matthew Pryor April 26, 2009 8:29 am
    #

    Hmmmm I am stuck trying to test the new code.

    I can run in the simulator fine, but when I try to run onmy 2.2.1 iPhone I get:

    2009-04-27 01:27:20.696 PhoneGap[9808:20b] *** -[UIControls createTabBar:options:]: unrecognized selector sent to instance 0x15a2a0

    Any clue what that is about?

    Thanks.

  7. Mike Nachbaur April 26, 2009 8:43 am
    #

    You might just have a stale build lying around from before your git merge. XCode isn’t smart enough sometimes to notice when files are changed. Do a “clean all” or delete your iphone/build directory.

    Let me know whether or not that works.

  8. J. Matthew Pryor April 27, 2009 12:17 am
    #

    Did all this with no effect.

    Maybe I am doing something wrong. I can see lines like this in UIControls.m

    [self createTabBar:nil options:nil]

    but there doesn't seems to be any such method.

    Sorry I am quite the Git & iPhone nube.

    Is there a better way to send you this feedback?

    Thanks,
    Matthew

  9. Mike Nachbaur April 27, 2009 8:54 am
    #

    Copy & paste an email to me with the contents of your debugger console output. Also, let me know what platform / version of the iPhone you're building for.

  10. davidroe April 29, 2009 10:47 pm
    #

    I’ve looked at it for 5 minutes. beautiful clean code, a joy to read.

    I have been playing with PhoneGap for a short while, your tab bar implementation looks like a much more efficient approach than my attempt. not being an Obj-C programmer (yet) I fudged something together using more lines to achieve less.

    I see you have a reference to Page2 in your HTML – is that just a hook for later?

    and I have used AxKit in the past, so I’ll take this opportunity to thank you for your work on sessions.

  11. Mike Nachbaur April 30, 2009 11:27 pm
    #

    Yes, it is a hook. I’m working on a little experiment. I’m trying to showcase how you can create animated panel flips and transitions easily using CSS3. I had a hard time figuring it out, so I thought it would be helpful for people to have a starting point to work from.

    Check out my “fancydemo” branch on github.

  12. Znoopy May 7, 2009 10:21 pm
    #

    This is amazingly well done! Thanks. I tried changing a navbar item through renaming it all over, and that works except I lost the icon for that navbar item. Also if I want a navbar item to open a URL in the main area (Page1) how do I target it like so in the html file? By default obviously it opens in safari.. Thanks again!

  13. Mike Nachbaur May 8, 2009 11:12 am
    #

    Znoopy: Ajax and innerHTML are your friend :-)

  14. Znoopy May 12, 2009 9:35 pm
    #

    Indeed. Tanks! One thing Ive noted is that the toolbar randomly dissapears, is this known?

  15. Mike Nachbaur May 12, 2009 9:44 pm
    #

    Check this thread on the PhoneGap google group:

    http://groups.google.com/group/phonegap/browse_thread/thread/b829353509cd446d

  16. foshizzle May 14, 2009 3:20 pm
    #

    Just grabbed your latest code. It seems as though not all tabbar items are created every time I run the app. Sometimes all of them are created (4 at the bottom), but sometimes it’s just 3, and not the same 3 either.

    The same goes for the Toolbar at the top. Sometimes it’s there, other times it’s missing.

  17. Mike Nachbaur May 14, 2009 3:26 pm
    #

    Please refer to the PhoneGap mailing list. This has already been discussed there. The short version of the story is that the accelerometer functionality gets in the way.

    In fact, I mentioned this on the comment immediately before yours. A little reading goes a long way.

  18. davidroe May 14, 2009 3:27 pm
    #

    I think the problem is two-fold: in phonegap.js, queue.ready seems to
    have the right values set but it is never checked before dispatching a
    command to PhoneGap. and secondly, the AppDelegate sets exec.ready to
    true, not queue.ready.

  19. Mike Nachbaur May 14, 2009 3:37 pm
    #

    davidroe: *VERY* interesting! That must’ve gotten messed up in a commit / merge somewhere, because that was working before.

    The following patch should do the trick, though I haven’t tested it yet. http://pastebin.com/f1fc64c7e

    I’ll get that merged in to the main branch soonish.

  20. Znoopy May 17, 2009 1:36 pm
    #

    Have you been able to successfully do a build on the iPhone using OS3? See here http://groups.google.com/group/phonegap/browse_thread/thread/9d20bced6c7509af

  21. Russ December 7, 2009 11:38 am
    #

    Great blog Mike!

    BTW, is there any more info on the “3rd party API integration, like AdMob and Medialets” that you were planning?

    I’m interested in integrating Admob into my PhoneGap projects and looking to follow others that have successfully done it to try to save what hair I have left. ;->

  22. Ryan December 9, 2009 4:35 pm
    #

    Is there any way to set it so the button in the nav bar on the right opens up a select box in the HTML? I can’t for the life of me figure it out.

    Also is there a way to change the text/image of the button in the navbar after it’s been clicked to something else?

    Thanks for all your great work so far! I love it!

  23. MobWeb May 13, 2010 1:29 am
    #

    Hey,

    I know this is old but I found it through Google: What happened to the AdMob integration into PhoneGap that you mentioned? It would come in really handy for us who use PhoneGap but don’t know any ObjC so we can’t implemenet AdMob into our apps. :S :)

  24. Michael Nachbaur June 18, 2010 3:30 pm
    #

    @MobWeb
    Whenever someone wants to step up and take over maintainership of my PhoneGap code on Github, I’ll give them the code I’d built to support AdMob. It’s not really in a publicly-consumable state, but if someone wants to volunteer to get it working on the latest version of PhoneGap, they’re welcome to it.