HelloPhoneGap1.0 Project Updated for PhoneGap 1.3.0

January 10, 2012 1 comment

I just updated the HelloPhoneGap1.0 out on github so that it works with PhoneGap 1.3.0, iOS5, and Xcode4 with the new project structure. Let me know if you see any issues…

Where to get the Code? (PhoneGap 1.3.0 Required)

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

PS. MAKE SURE YOU INSTALL PHONEGAP!

About these ads

Debugging iOS Apps Using Safari Web Inspector

November 22, 2011 13 comments

 

Enabling Remote Debugging using Safari Web Inspector for iOS

 
Wow! What a day! While researching debugging techniques for an upcoming training class I am teaching on PhoneGap, I stumbled over a couple of blogs about a private API in iOS5 that will allow you to debug your UIWebViews right inside desktop Safari using the Web Inspector!

It’s so simple! All you have to do is add this to your AppDelegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Uncomment to enable remote debugging
    [NSClassFromString(@"WebView") _enableRemoteInspector];
....

Then use Safari to access http://localhost:9999 and you are debugging with Web Inspector and have full debugging capabilities including breakpoints and DOM manipulation among other things!

It only works on iOS5 and it only works when running in the simulator BUT it’s an awesome upgrade from Weinre if you are building an iOS app.

Kudos to @atnan for finding it!!

References

See this blog by @atnan for more info and tips for enabling debugging for Mobile Safari in iOS.

Also see this blog by @firt for a nice tool – iWebInspector – that makes enabling debugging a little easier.

HelloPhoneGap1.0 Project updated for PhoneGap 1.1.0

October 28, 2011 34 comments

I just updated the HelloPhoneGap1.0 out on github so that it works with PhoneGap 1.1.0, iOS5, and Xcode4 with the new project structure. Let me know if you see any issues…

Where to get the Code? (PhoneGap 1.1.0 Required)

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

PS. MAKE SURE YOU INSTALL PHONEGAP!

HelloPhoneGap1.0 Project Created – Compatible with iOS 5, PhoneGap 1.0, and XCode4

August 17, 2011 24 comments

I just created a new project HelloPhoneGap1.0 with the code out on github so that it works with PhoneGap 1.0, iOS5, and Xcode4 with the new project structure. Let me know if you see any issues…

Look for an upcoming post that details the changes in the project structure and how to go about extending and updating the PhoneGap library in the new project.

Where to get the Code? (PhoneGap 1.0 Required)

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

HelloPhoneGap Project Updated for PhoneGap 0.9.6

June 29, 2011 5 comments

 
Just updated the code out on github so that it works with the 0.9.6 PhoneGap. Let me know if you see any issues…
 

Where to get the Code? (PhoneGap 0.9.6 Required)

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

Debugging PhoneGap & JavaScript

 

How to Debug PhoneGap and JavaScript

 
If you have ever written any JavaScript and tried to get it working on a mobile phone then spent hours banging your head against the wall because it just doesn’t work, this post is just for you. Today, we will be looking at ways to troubleshoot, diagnose, and debug your mobile web project. While I will be focusing on debugging interactions with PhoneGap, the strategies outlined here are really applicable to any JavaScript or mobile web project. Since I have been focusing mainly on iOS development, this post will discuss the debugging of JavaScript and PhoneGap within an iPhone application but the same ideas should work for Android and other platforms as well.

Pre-requisites:

 

Where to get the Code?

 
To demonstrate the troubleshooting and debugging strategies outlined below, I will using the HelloPhoneGap project that I created for my PhoneGap Tutorial Series.

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

 

Common Problems

 
Over the course of putting together various applications, I have undoubtedly made many mistakes and spent many hours trying to figure out what went wrong. I have misplaced quotes, brackets, mistyped JSON and struggled with writing well-formed JavaScript that “looked right to me.” I have misspelled method names, overwritten global variables, and forgotten to “install” my PhoneGap plugins. I have also tried to use PhoneGap methods in inappropriate locations and sometimes couldn’t figure out why the feature works on my phone but doesn’t work in the simulator. After all of those hours of trial and error, I would like to share some of the strategies that I used to help figure out my mistakes.

Tip #1 – JavaScript Syntax Validation

So you wrote some JavaScript, added it to your page, wrapped it in PhoneGap, launched it in the simulator, waited patiently for a bit, clicked your mouse, and nothing happened. Huh? No errors, nothing. What could possibly be the problem? Well, there are many possibilities but the most likely is that you have malformed script. When running in a webView the JavaScript engine isn’t very forgiving when it comes to mistakes and it doesn’t bother to tell you about them either. Your page may render and the html may look pretty but if you missed a bracket somewhere you won’t get a nice little red icon or a full suite of debugging tools to help you figure it out. When running on the simulator or even on your phone, you do not have the same tools that you would have if you were running in a desktop browser. So, what to do?

Depending on your development tools, you may or may not have decent support for JavaScript. If you are writing an iPhone app, you are most likely using XCode for your development. You probably have nice color coding and some not-so-smart code completion but if you want to write well formed JavaScript it doesn’t really help all that much. What you can do is use a tool called JSLint to validate your code and point out those not so obvious syntactical errors.

There are a couple of ways run JSLint:

  • JSLint.com — this website allows you to cut and paste your code into a form and it will validate your code
  • JSHint.com — some people may feel that JSLint.com is a little too restrictive, if you are in this camp then you could also try using JSHint.com.
  • SproutCore Bundle for TextMate — the nice folks at SproutCore have built a free bundle for TextMate that you can use to run JSLint right from within TextMate. Just install the bundle and run the “Validate Syntax” command. The bundle uses the JavaScriptCore.framework library from Apple to run the JSLint scripts. The bundle can also “beautify” your script which is pretty handy as well.

JSLint can handle standalone script files as well as html files with script tags but there are a few limitations:

  • All tag names must be in lower case.
  • All tags that can take a close tag (such as <p></p>) must have a close tag.
  • All tags are correctly nested.
  • The entity &lt; must be used for literal ‘<’.

If you use TextMate, you can make sure that your HTML code is compliant prior to running JSLint by running the “HTML Tidy” command first.

Tip #2 – JavaScript and HTML inspection

After making sure that you have well-formed JavaScript and you are convinced that can’t possibly be the problem, the next step is … debug! Oh, wait….there isn’t really a JavaScript debugger available for the iPhone webView! Now what?? Well, Patrick Mueller has released an awesome tool – Weinre – that will allow you to interact with your webView remotely. You can inspect and edit the DOM, CSS, view log messages and even run JavaScript on the fly. It’s the closest thing to an actual debugger for the mobile web that I have seen to date and while it takes a bit of effort to get set up and running, it’s well worth it.

You can download Weinre from github and detailed instructions for installing and using it can be found here. The Weinre server app provides the tools to interact with client WebKit browsers. In order to make this happen you must set up and run the Weinre server and then add a script tag to each page of your web app that you wish to inspect and interact with.

The client side Weinre script uses AJAX to establish a connection and communicate with the Weinre server and allow the on demand inspection and editing of the DOM, CSS, and JavaScript. Jonathan Stark, author of Building Apps with HTML, CSS, and JavaScript, has put together a nice screen cast of Weinre in action – you can view it here.

Once everything is up and running, you can use the Weinre tools to check that PhoneGap has been initialized and that you are using the correct PhoneGap API with the proper parameters. You can also inspect the DOM and your CSS, dynamically make changes and see how they may impacts your mobile site in real time.

Now, just so you don’t make the same mistake that I did — don’t forget to remove the Weinre script from your pages when your are done debugging your pages. I lost hours one day when my app was suddenly hanging until I realized that I had forgotten to remove the script and my app was timing out looking for the Weinre server that no longer existed.

Tip #3 – JavaScript Debugging in the Desktop

Now that you have verified that your script is well-formed and had a chance to inspect your site with Weinre, you may still have a problem and really only debugging will do. Well, there is always the poor man’s debugger: “alert(“made it here!”);”, but that’s not very useful if you are using a lot of JavaScript or are dependent upon third-party libraries like JQTouch or SenchaTouch to do most of the heavy lifting for you. So, what else is there to do? Debug your app using your favorite browser based tool set of course! (I used Safari and Web Inspector….)

I know what you are thinking! It’s a mobile browser! How am I supposed to debug it! The answer is that you aren’t. You are going to debug your HTML, CSS, and JavaScript app in a desktop browser. The trick is to remove any dependencies that you have on PhoneGap before debugging. There are a couple of ways to go about this but the basic gist is to use some sort of mechanism to replace the PhoneGap calls with something else – a PhoneGap “shim” if you will. Several people have made their versions available out on github with varying degrees of capability.

PhoneGap “shims”

  • https://gist.github.com/476358 — this snippet comes to us from Jesse MacFayden (@purplecabbage) and allows calls to be made to PhoneGap without causing JavaScript errors. With a little editing I was able to show an alert with the details of the phonegap command that would have been executed. To see the edited version – open the PhoneGapShim1.js in HelloPhoneGap project. I tested it out using the camera.html and the geolocation.html files in Safari.
  • https://github.com/alunny/stopgap — this snippet basically just wipes out the PhoneGap object and fires the ondeviceready event. This might be useful if you don’t rely on PhoneGap for all that much beyond display and don’t care about testing your interaction with the PhoneGap device APIs.

Overall, the shims that I found were a little lacking but there is nothing stopping you from rolling your own. With a little more manipulation, the snippet from @purplecabbage could be easily extended to provide a more robust framework to mock out PhoneGap and simulate device interactions.

That’s all for now! Stay tuned for future posts and don’t forget to check out my PhoneGap Tutorial Series!

PhoneGap Tutorial Series – #6 Writing Your Own Plugin

April 15, 2011 9 comments

 

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!

Follow

Get every new post delivered to your Inbox.

Join 34 other followers