Friday, January 27, 2012

Books I've Read This Week


Reality Is Broken by Jane McGonigal reminded me of an idea I was toying with implementing back when I was a software development manager. Back in those days no one liked doing their yearly review as it truly was a pain in the ass to keep track of your yearly achievements and it really didn't amount to anything as pay cuts and not raises were the order of the day. I wanted to implement an experience points system for my developers. For each bug they fixed, test case they wrote or document they reviewed they would get experience points. Then at the end of the year they would have a good record of what they had done and a quantitative number to compare against last years performance. Ideally the developers would get more points for the less desirable tasks. For instance fixing a bug would be worth less points than writing a test case. I hoped that it would incent people to pay more attention to some of the things we are no are important but are often ignored in software development. Alas, it was not to be.

As a gamer and software developer I really identified with the tenants of this book. I'm supremely lucky to have a job in which the motivations for me to come to work every day are more intrinsic than extrinsic and at this point I can't ever imagine going back. During the day I tend to answer a lot of questions about PhoneGap on the Google Group or on StackOverflow. I get more satisfaction from StackOverflow as it provides me feedback on my answers. They are up voted and accepted by other users of StackOverflow. This feedback I get from other users gives me intrinsic motivation to keep going.

The notion of using gaming to enhance and improve reality is fascinating one and very well articulated in this book. I will have to agree that collaboration is going to be one of the key skills of the 21st century. Without collaboration we will be unable to get past the challenges we currently face.

Here is a great Ted talk by Jane McGonigal that may whet your appetite for this most excellent book:

Hellboy Volume 11: The Bride of Hell and Others is another good volume from Mike Mignola in the Hellboy ouvre. While it does not exactly move the story forward that we've seen back in Hellboy volume 9 it is a good collection of Hellboy stories and is worth reading for Hellboy and the Luchador's!

See you next Friday.

Friday, January 20, 2012

Books I've Read This Week


Steve Jobs by Walter Isaacson in a word is mesmerizing. This is a great no holds barred biography of a complicated man. Jobs was such a polarizing figure as many folks loved him while other absolutely detested him. Although the one thing you can't argue with is that he had a huge impact on technology. Jobs was the driving force behind Apple who've given us the Macintosh, iMac, iPod, iPhone, iPad which revolutionized the computer, music and phone industries. As well he was deeply involved in Pixar which has brought us some of the best movies of the past 20 years. That's not to say that he hadn't made a number of mis-steps along the way, NeXT for instance.

To Jobs things we either insanely great or shit. There was no in between for him as his opinions were of a binary nature. He was extremely hard to deal with and the book gives us an unvarnished view of his relationships with friends, family and business partners.

This is one of those books released in 2011 that is a must read.

See you next Friday.

Friday, January 13, 2012

Books I've Read This Week

Keeping in line with my new years resolutions my books have taken a turn towards non-fiction

Psychopath Test by Jon Ronson is a very interesting book the details how to detect psychopath's by answering a 20 question test. As the author mentions in the book once you start detecting psychopaths you'll start seeing them everywhere which is a bit of a problems. However, it is a great insight into how some folks brains are wired incredibly different than the average.

Great By Choice: Uncertainty, Chaos, and Luck--Why Some Thrive Despite Them All is the latest in a series of books by Jim Collins. In it Collins examines a number of companies to determine what specific choices they've made in order to become great. Some of the qualities that emerged were the great companies didn't take crazy risks, first they tested their assumptions a little at a time before deciding to jump in with both feet and when things are going well that is the time where the great companies get extremely paranoid about how it could all go wrong.

See you next Friday.

Wednesday, January 11, 2012

Book Review: PhoneGap Beginner's Guide

Phonegap Beginner's Guide by Andrew Lunny delivers exactly what the title promises as it is a good guide to developers just getting started with PhoneGap. The book walks you through the installation of the PhoneGap framework, shows you how to develop and debug your application in a web browser before bringing it over to the device and describes a number of HTML5/CSS3 features you can take advantage of without even needing PhoneGap. Then the book walks you through a number of areas of device functionality that the PhoneGap API like the accelerometer, camera and contacts. Plus there is a chapter devoted to extending PhoneGap functionality using the Plugin API.

The only con that I can point out is that the book does not completely describe the available PhoneGap API, nor should it really as it is targeted at beginners. I can't fault Andrew at all as a lot of the currently functionality was delivered after the books was sent to be published. One thing you should be aware of is that chapter 9 describes the navigator.service.contacts interface which is now navigator.contacts.

I do recommend this book for PhoneGap and fledgling hybrid mobile application developers. Probably the easiest way to get it is as an ebook from Packt.

Friday, January 6, 2012

Books I've Read This Week

I had to return The Children of the Sky back to the library but here are some other books I read.

For the Love of Physics is a great read that explains physics in laymen's terms by Professor Walter Lewin. It is well worth the read if only for the chapter in which he explains rainbows and how to spot the easier. As an added bonus you can get all of Professor Lewin's entertaining lectures on physics courtesy of MIT's open course ware.


Scalped Vol. 1: Indian Country by Jason Aaron is a series I've been meaning to check out for awhile. Set in a fictional Indian reservation undercover FBI agent Bad Horse returns home to take on a corrupt reservation chief and casino owner while dealing with his activist Mom and ex-girlfriend. It sounds very soap operaish but this was a great crime comic.

Kamandi Last Boy on Earth Omnibus Vol 1 by Jack "The King" Kirby is pretty amazing. Published during a time where the Planet of the Apes movies were hot properties the similarities are obvious. Kamandi is the last reasoning member of the human race. After his grandfather dies his leaves the bunker he's lived his whole life to explorer the world where he encounters Lions, Tigers, Apes, etc. that have evolved to become the dominant species on earth while humans have regressed to near unthinking animals.

Each and every one of the 20 issues in this omnibus is just bursting with ideas. There is so much going on in these pages that it is too hard to get it all into one blog post. At the end of the first issue there is a map of North America so you can see Kirby had a plan for where he wanted to take this series. Also, while this comic was being published Jack Kirby was doing two other monthly books so he was producing upwards of 60 pencilled pages of art. These days, it's hard enough to get an artist to do 20 pages a month consistently. The pure draftmanship of this book is outstanding.  

See you next Friday.

My New Year's Resolutions

It's about a week after new years and I've been thinking a lot about this years resolutions as I'm going to take them seriously this year. Some of them might seem pretty odd if you just read the titles. Honestly, this isn't a post for you blog readers it's much more for myself. I figure if I put it out there people will call me on it and I'll be more likely to keep my resolutions.

Read Less

Last year, according to my Shelfari account, I read 218 books. Breaking them down into genre looks like this:


The pie is dominated 68.7% by Comics and Manga. Predominantly that was taken up by some epic runs of manga like Monster, 20th Century Boys, Naruto and One Piece and graphic novels like Preacher, B.P.R.D. and Fables.

This upcoming year I'm going to read less books and change my focus to Technical and Non-Fiction books. I have a lot of eBooks I've bought from O'Reilly's Deal of the Day that are just begging to be read. I'm targeting that come the end of 2012 the technical and non-fiction portions of this pie will be about 50%.

It's not that I don't enjoy comics/manga I just need to concentrate on some different things this year.

Exterminate, Exterminate, Exterminate

With Dalek like dispassion I'm going to remove a lot of stuff from my life. The first thing I'm going to do is look at the information overload. I currently subscribe to 106 RSS feeds in Google Reader, follow 308 people on Twitter, subscribe to 38 podcasts and get an enumerable amount of emails a day. I'm going to be absolutely brutal about killing feeds, un-following, deleting podcasts and unsubscribing from email lists until I can reduce the incoming information by a minimum of 25%.

At home I'm going to get rid of a number of books, DVD's and comics that are frankly just collecting dust. There is just too much of my junk cluttering up the house and especially my office. I'd love to hear what suggestions people have for old books and comics. Right now I'm thinking about making a rather sizeable donation of used books to the amazing Ottawa Public Library and a bunch of comics to CHEO.

The extermination will not spill over into other time wasters in my life. I'm going to cut back on my TV viewing. It's not that I watch a lot of TV but I want to shift those hours spending more time reading or creating. I've already got a PVR I built myself using BeyondTV at home to that saves from commercials and appointment viewing but a few shows may not make the cut in 2012. Nathan Fillion I love you but Castle hasn't really been that good this season with the introduction of Captain Victoria Gates. That character has been poison to the show. Also, How I Met Your Mother would benefit a lot by phasing out Ted as a character. Maybe he can architect a building in Dubai or something.

The Obligatory "Get in Shape" Goal

It's not that I'm in bad shape. I play ice hockey twice a week and I'm pretty fit for a man of my advancing years. However, I could stand to lose a few pounds. I'm a bit scared that I'm developing that skinny fat guy disease. I don't think I'll ever get back to the days where I'm doing a couple of triathlons a year but I'm going to make the commitment to fitness this year one of my top priorities. To that end, the opening of the new gym in my building can't come soon enough.

One thing that I know will make a big dent is:

NO. MORE. SODA.

I've gotten back into the bad habit of drinking soda pop with meals. I blame Christmas and having the devils drink at home for people who were visiting. Unfortunately, I started drinking it again at home and then while out of the house but no more!

Look forty, I'm going to be ready for you. If you plan on hitting me hard in a couple of years I will be ready to hit back.

Publish or Perish

Recently Dean Haspiel published an article called Publish or Perish that was inspired by a tweet from comic book writer Jimmy Palmiotti. Basically Dean posits that freelancers now have the all the tools they need to publish their own work or get run out of the business. The post deals with comic book professionals it is all very germain to software developers.

While I'm not going to do anything to jeopardize my incredible day job that allows me to work on PhoneGap on a daily basis I am going to do some things that stretch the bounds of my current role.

I will publish my first application to the Android Marketplace. It will be for free and it will be open source. Beyond that I have a few other ideas for applications but at a minimum I will get this first app out early in 2012. It may not help anyone else but it will fix a problem for me.

I will write my first book. It may never get published but I will write it. Wait scratch that, it will get published as there are a couple of publishers who have expressed interest and if they don't want to release it I will self publish it. There I said it, I'm doing it.

Obviously, it will be a technical book. I don't think the world is ready for my take on Batman but hey DC Comics if you want to hear my pitch just let me know.

Thursday, January 5, 2012

On the Twelfth Day of PhoneGapping: User Contributions

Did you know if there is a missing bit of functionality in PhoneGap you don't need to wait for the core development team to get around to it? You can take matters into your own hands since PhoneGap is an open source project.

Let's say you have a bit of functionality that is only required on one platform, well the best thing to do in that case is to write a plugin. If you want to share your plugin with the world then let us know by submitting a pull request on the PhoneGap Plugins repository. Submitting to this repository only requires for you to have a GitHub account. There is no need to sign any contributor license agreement. We love to get new plugins.

However, let's say you've identified an area of the API that is lacking. Until PhoneGap 1.3.0 there was no download function for the FileTransfer class. Well developer Alexander Heinrich decided to fill that niche by submitting pull requests that added the functionality to iOS and Android. That was a huge help and the BB developers were able to step in an fill in the functionality in their repository. Up until that point Alexander was not a member of the core PhoneGap developers but after he signed the Apache ICLA and we reviewed his code he was in. It's as simple as that.

So to all of you my challenge is for you to be the next Alexander Heinrich! Create a plugin, fix a bug add new functionality.

Wednesday, January 4, 2012

On the Eleventh Day of PhoneGapping: Configuration Defaults

As much as we'd like to make PhoneGap 100% cross platform there are some differences between platforms that sometimes need to be smoothed over. Two items that I can think of off the top of my head are:

1) Android's persistent file system defaults to the SD Card which everyone can read from while in iOS it defaults to a directory that only the app can read.

2) In order to play a Media file the path to a file in the www directory is different for Android and iOS.

So to smooth these difference over you can create a .json file that is included in your www directory which will hold platform specific configuration details and load it via XHR. Here's how to do it:


Your .json file on Android could look like:

{ 
    "mediaPath": "/android_asset/www/"
}

and on iOS it would look like;

{ 
    "mediaPath": ""
}

So now you can replace clunky if statements like:
if (device.platform == "Android") {
    var my_media = new Media("/android_asset/www/test.mp3");
} else {
    var my_media = new Media("test.mp3");
}
with:
var my_media = new Media(Config.mediaPath + "test.mp3");
and continue to access everything in a cross platform way.

Tuesday, January 3, 2012

On the Tenth Day of PhoneGapping: Searching Contacts

As I've mentioned before some of the W3C specifications that we base the PhoneGap API on are the difficult to understand. The Contacts API is definetly one of the hard to understand ones. Here is an example of searching the phones contacts and handling the gotchas that may arrise.

First here is the method signature used when searching contacts:


navigator.contacts.find(
    contactFields, 
    contactSuccess, 
    contactError, 
    contactFindOptions);
contactFields [Required]: is an array of strings that represent the fields from the Contact object you want returned as part of the search results. For example if you wanted to get the contacts display name and email addresses you would specify:
["displayName", "emails"]
if you would like to get each an every field populated in the returned array of Contacts you would specify, what I call, the fire hose option.
["*"]
However, be careful not to specify too many un-needed properties in the contactFields array. The array does double duty in the find command as the filter you specify in contactFindOptions is applied against each and every field in the contactFields array but we'll talk about that more later.

contactSuccess [Required]: is the success callback which is invoked with an array of contacts.

contactError [Optional]: an optional error callback which is invoked if something goes wrong with the find command. The only parameter to the function is a ContactError object.

contactFindOptions [Optional]: is an optional ContactFindOptions object which controls a couple of options in the find command. The two parameters in the contactFindOptions are

filter: specify what you want to match against.
multiple: set to true if you want more than one contact returned in the success callback.

by default filter is set to the wildcard (match everything) and multiple is set to true.

Find Examples

1) Find all the names and email addresses of contacts with Ottawa area phone numbers.
navigator.contacts.find(
    ["displayName", "name", "emails", "phoneNumbers"], 
    contactSuccess, 
    contactError, 
    {filter: "613", multiple: true});
2) Get all the contacts on the device.
navigator.contacts.find(
    ["*"], 
    contactSuccess, 
    contactError);
3) Find all contacts named "Bob" and where they work.
navigator.contacts.find(
    ["displayName", "name", "organizations"], 
    contactSuccess, 
    contactError, 
    {filter: "Bob", multiple: true});
Gotcha's

1) Slow search results.

As I mentioned earlier the more items you specify in contactFields the longer your search will take as the filter will have to be applied against it to see if the contact matches the filter. Please try and limit the contactFields array to only the parameters that you absolutely need.

2) Null values

Frequently people end up running into errors in their success callbacks as they don't guard against null values properly. According to the W3C spec if there are no results for array values like emails, phoneNumbers, addresses, etc. the code should return a null for theses values and not an empty array. So when folks try to loop through all the returned emails it will error out as you can't access the fields of a null value. So when you try to access one of these values guard agains the null.
if (contacts[i].phoneNumbers != null) {
    for (j=0; j < contacts[i].phonenumbers.length; j++) {
        // Do stuff
    }
}

On the Ninth Day of PhoneGapping: Getting Help

Besides being an excellent JavaScript toolkit PhoneGap is also a kick ass community of developers. The best place I know of to get help, and where I hang out answering a buch of questions is the PhoneGap Google Group. As well there is an IRC channel at irc.freenode.net, port 6667, with a room name of phonegap obviously.

In order to improve your chances of getting a quick and informative answer I'd suggest that you follow this process when asking a question on the Google group or on IRC.

First search the archives

Your question may have already been answered. Make sure you search at least PhoneGap Google group archives before you ask your question. Go to the PhoneGap Google group and use the search field in the top right of the page.

Provide details

Give as many details as possible. Incomplete questions won't likely be answered.

Include the following at a minimum:

  • what version number of PhoneGap are you using?
  • which platform and version you are testing on? iOS 4.0, Android 2.2, BlackBerry 6.0, etc.
  • a detailed description of your problem.
  • is this happening in the emulator only, phone only or both?

Select a concise, informative subject for the post. For example, include:

  • Platform, if issue is specific to Android, iOS, etc
  • Keyword examples: version, jar file, phonegap plugin, deviceready event, build
  • Short phrase summarizing the problem

You may also want to include:

  • some sample code that illustrates the problem.
  • logs taken while the problem was reproduced.

If the code or logs are huge, let's say over 20 lines please think about using a web service like Gist or Pastebin.com. Alternatively if you have a Dropbox account put the file in your public folder. Then share the link in the email rather than mailing around a bunch of large files.

An example of question

Wrong:
PhoneGap does not work for me!

Right:
I get a security error on PhoneGap 0.9.4 when I try to open a database using the Android 3.0 emulator. You can see the code I used here: https://gist.github.com/937307 and the logs I collected here: https://gist.github.com/937315. I have looked at the archives and the commits but did not find any solution. Does anyone know what could be the issue and whether this has been fixed?

An example of subject


Wrong:
Urgent. Need help with my problem.

Right:
Android / PhoneGap 1.2.0 : deviceready event not firing

Sunday, January 1, 2012

On the Eight Day of PhoneGapping: Multiple Screen Sizes

This is another question that comes up on the mailing list frequently, how do you support multiple screen sizes (portrait, landscape, phone, tablet)? Luckily there is a pretty good technique in web development that can be used in your PhoneGap application. It is called responsive web design and there is a book by Ethan Marcotte coincidentally called Responsive Web Design that I've recommended so often that I feel like I should be getting a kick back from the author (Full disclosure, I don't get a kick back). The book is only $9 and after you are done reading this post you should just go buy it.

In a nutshell, responsive web design uses CSS media queries to determine the width of your display and deliver different layouts based upon screen size. This would allow you to show a single column interface to portrait based phone users of your application but a multi-column approach to landscape table users. Let's run through a quick example.

For our phone users we'll setup our CSS so that our navigation sidebar shows up at the top and the main area of our application is underneath it. That would require some CSS that looks like this:
#wrapper {
            width: 90%;
            min-width: 0;
          }
          #main {
            margin-left: 0;
          }
          #sidebar {
            width: auto;
            float: none;
          }
We'll set our wrapper div to have a width of 90% because we don't want any text going right up against the screen as it make it hard to read. We'll give our main content a left margin of 0px so it is left justified against the wrapper div. For our sidebar we'll make the width auto so all the text will fit. So you app will look like this:


Now for the tablet version of the app you have a lot more screen real estate to work with so you want to have two columns. The left column will be the sidebar for navigation and the right column will be the main content area. Your CSS will look like:
#wrapper {
              width: 80%;
              margin: auto;
            }
            #main {
              margin-left: 40%;
            }
            #sidebar {
              width: 40%;
              float: left;
            }
The first thing you will notice in the CSS is that the wrapper div width is now 80% as we have more screen to work with so we can pad the sides a bit more. The main div is going to float over to 40% of the width of the wrapper div and the sidebar will be 40% of the wrapper div floating to the left side. And your app would look like this:


So that is all well and good but how does our app choose which version of the CSS to use depending on if it is running on a phone or tablet. Well that is the magic of CSS media queries. We'll wrap up our CSS with:
@media all and (max-width: 800px) { ... }
for the phone version of the CSS and:
@media all and (min-width: 801px) { ... }
for the tablet version. Simply screens up to 800px will get the phone version of the CSS and any screen over 800px wide will get the tablet version.

Here is a full HTML file for you to test out.


Interestingly enough for Android 3.2 and greater they've adopted a similar technique to responsive web design to handle multiple screen sizes on Android.