Tony Lukasavage

Caffeine. Whiskey. Code. Mostly the last one.

Sneak Peek at “Knuckle Head” for iPhone

Knuckle Head, Take 2

Here’s a sneak peek at the soon-to-be-released iPhone version of my MMA fighter app Knuckle Head, built with Appcelerator. I chose to do the native Android version first, as it allowed me to iterate through versions very quickly, making changes as users gave me feedback. Now I can apply that feedback without having to go through Apple’s much slower approval process with each iteration.

There were 3 main drivers behind this port:

  • The Android version has been rated really well so far, and I’ve had requests for an iPhone version.
  • I will be joining the Appcelerator team in a week and a half, so this seemed like a great way to sharpen my skills with it.
  • I was just curious how the download and ad fill rate numbers would stack up against each other with a niche app like this one on Android and iPhone.

Also, there’s a chance I will open source this and put it all up on Github once it’s approved for the Apple App Store. If there’s any interest let me know. If not, I’ll probably turn out some blog articles based on things I learned doing this port. The short version is that Appcelerator definitely has its quirks, but is in all likelihood going to be your fastest route to a quality iPhone app. I went from zero to complete port in about 20 hours of work.

And that doesn’t even get into the cross platform potential. Expect a lot of content going forward on how you can turn the “potential” of cross platform code into “actual” cross platform code using Appcelerator.

Knuckle Head for iPhone video

So here it is, in all its water-marked, sub par quality glory. You’ll have to forgive those issues, I’m currently evaluating ScreenFlow. Seems like a good tool so far, but I don’t like shelling out $99 for software without playing around with it a little bit.

Appcelerator’s Latest Acquisition… Me!

2 Days in the Valley

Yes, the developer/blogger with no allegiance to any mobile platform has finally found a home. I spent 2 days in Silicon Valley at Appcelerator HQ meeting the crew and getting to know more about them. In that time I had the pleasure of speaking with Tony Guntharp, Jeff Haynie, Scott Schwarzhoff, Kevin Whinnery, Matt Apperson, and Anthony Decena. Needless to say, I was VERY impressed by them as individuals and as a team.

As it turns out, although I’ve been very critical as of late regarding Appcelerator, they respected the concerns I brought forth. They actually seemed to view them as a blessing in disguise. For every loudmouth like me there’s 100 who make no mention of their issues with the platform.

Major efforts are currently underway to make Appcelerator even more developer friendly. If you have not heard yet, as of the 1.2.0 release of Titanium Studio, integrated mobile debugging is now free. As you might have guessed, this was a big talking point between me and the Appcelerator guys in light of the less than complimentary post I wrote regarding their initial charging for it, which has since been ammended.

In addition to free debugging, Appcelerator has made a copious amount of training videos free for developers. As a compliment to their existing API documentation, wiki, and Q&A section, these videos are more than just a quick start. They deal in depth with coding conventions and best practices for developing high quality Appcelerator apps.

So where do I fit in? I will be in the role of a Platform Evangelist. Yeah, I know, sell out. But hey, at some point you need to pick a horse and commit. And in the advent of the incredible popularity of DOM-less Javascript (see Node.js) and mobile development, it only made sense to pick the platform that is championing both. Plus, with the brief look I got under the hood of Appcelerator’s operations, I see nothing but exciting things coming, things I would love to be part of.

Things to Come

What does this mean for the content of my blog? Not sure yet, but don’t count on it turning into Appcelerator-only love-fest. There’s just too many other things I’m interested in. Obviously much of my work will be geared towards Appcelerator and showing off what it can do. In doing so, though, I’ll fortunately have plenty of opportunities to demonstrate native Android and iOS code, code that can then be turned into Appcelerator modules. Yes, it is a very interesting time indeed.

Stay tuned…

Gonzo, an open source markdown editor

Gonzo

Gonzo is a lightweight, open source markdown editor written for Adobe Air for desktop using Flex 4 and AS3. Its a stripped-to-the-bone application that serves one purpose: helping you deliver well formed and easy to proofread web content.

Gonzo, the lightweight markdown editor

Why use markdown, I already know HTML?

Rather than drone on about the pros and cons of each, I’ll just present you with a simple example. You let me know which version you would rather proofread.

HTML version

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<h2>Here's a header</h2>

<p>Here's some content in a paragraph. And here's a link to <a href="http://www.google.com">Google</a> and another to my <a href="https://github.com/tonylukasavage">Github</a> account.</p>

<p>And here's another paragraph
    <blockquote>this time it contains a blockquote</blockquote>
</p>

<ul>
    <li>One of these lists' syntax</li>
    <li>has the following attributes:</li>
    <li>
        <ul>
            <li><b>intrusive</b></li>
            <li><b>ugly</b></li>
            <li><b>very hard to read</b></li>
        </ul>
    </li>
    <li>which one do you think it is?</li>
</ul>

Markdown version

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## Here's a header

Here's some content in a paragraph. And here's a link to [Google][] and another to my [Github][] account.</p>

And here's another paragraph
> this time it contains a blockquote

* One of these lists' syntax
* has the following attributes:
    * intrusive
    * ugly
    * very hard to read
* which one do you think it is?

[Google]: http://www.google.com
[Github]: https://github.com/tonylukasavage

Why should you use Gonzo?

Well, unless you are writing content for the web, you probably shouldn’t. Gonzo is written specifically for those who want to leverage the readability of markdown over HTML when publishing web content. So whether you are writing a Wordpress blog post, editing a wiki, or even just an answering a question on StackOverflow, Gonzo can make your life a whole lot easier.

In the spirit of markdown, I’ve added just enough features to increase efficiency while maintaining a content-driven writing experience. The idea is to only add features necessary for making web publishing easier. All the effort saved by not implementing useless features was redirected into usability.

Just Give Me The Feature List Already

Yeah, I tend to skip the text and go right for the feature list too. Kudos to anyone who actually read the previous content before coming here.

  • Live HTML preview - You can actually see the raw and rendered HTML generated by your markdown in a preview pane.
  • Multi-tab editing - Edit many documents at the same time.
  • Cross platform - Works on any desktop that supports Adobe Air.
  • Keyboard and (context) menu shortcuts - Creating markdown is even easier now with multiple was to create it.
  • HTML Export - Export your generated HTML to a file so it can easily be uploaded or shared.
  • Cheat Sheet - integrated markdown cheat sheet for beginners and vets alike.

Coming soon…

This is the list of features I personally would like to have, as I’m the only user so far. Please let me know what you think would be a good addition to Gonzo’s functionality.

  • yfrog integration - Wouldn’t it be nice to browse to a file on your desktop, upload it as an image, and get a markdown link placed in your document in one click? I think so too.
  • bit.ly integration - see above
  • Markdown toolbar shortcuts - Just in case the keyboard, context menu, and native menu shortcuts aren’t enough…
  • Preferences - Let users set things like fonts, colors, editor sizes, and eventually maybe even theming.
  • Local settings - For persisting preferences between Gonzo sessions

What else do you have in mind?

Want to Contribute?

Good! Like most open source projects, ongoing development will be heavily motivated by contributions and feedback from its community of developers and users. While Gonzo will continue to grow as I use and find features I want, its going to be you who determines if it matures into an application for the masses.

There’s a number of ways you can contribute:

  • Use it and let me know what you think.
    • What is it missing?
    • What am I doing wrong
    • What am I doing right?
  • Fork Gonzo on Github, start hacking away, and send me some pull requests. I’m very open to help, but bear in mind that its lightweight nature and usability should not be sacrificed for the sake of features.
  • Design help is very welcome. I’m a dev through and through, so it will remain spartan in frills unless someone else decides to add the polish.

Summary

There’s a lot to come yet for Gonzo. I still need to get the wiki up and running for basic docs. I may even take the time to make a web page for it if it garners enough interest. Or none of this could happen and I could just continue to use it myself. Only time and feedback will tell.

If you do start using or hacking Gonzo, you can let me know here, on Github, or on Twitter. I’d love to hear about your experience. In the meantime I’ll continue using it to write my web content and keep improving it as I see fit.

Oh, and this entire post was written in markdown using Gonzo. Here’s a link to the original markdown for the blog post.

Waiting for Android: UrlJsonAsyncTask

When creating my MMA fighter search app for Android, Knuckle Head, I created a class that I have reused a few times since. Its called UrlJsonAsyncTask and the code necessary to use it is available in my com.savagelook.android project on Github. The following excerpt describes the problem it was built to solve:

I can’t even count how many times I’ve had to load a ProgressDialog in Android, query JSON from a remote URL, and then return control back to the app once the query has completed. It’s an incredibly common control flow, and one I’m sick of doing over and over again. I’m sure I’m not alone. In effort to keep this a DRY situation, the class UrlJsonAsyncTask in my collection of Android helpers, com.savagelook.android, is dedicated to the aforementioned task. It reduces what can be an 80+ line of code endeavor, per task, down to about 15 or less.

For the rest of the article, head over to the full article at BuildMobile.com and check it out. The full article includes a full explanation of the code, a test project with full source, and even a downloadable Android app for testing the functionality yourself.

11 Vague Ways to be Technically Relevant

These are the tips I suggest, and follow myself, for becoming and remaining relevant in the arena of my technical interests. I’m not promising what the SEO and social media marketers promise in terms of universal popularity. I’m just offering a hard working path to making your work, content, and opinions relevant to your target technical audience.

A lot of these tips are vague and obvious. I’ve found, though, that hearing common sense from someone else or seeing it in print often works as a catalyst for actually acting on it.

Exist

Get yourself a blog to have a home for your original content and work. People need to know you exist as a unique entity. Sign up for a cheap plan at one of these hosting solutions:

Fire up a default Wordpress install and get started creating original content. Don’t waste a lot of time on Wordpress themes and plugins. While fun, they are a huge time sink and you’ll likely change it all at a later date anyway. Spend no more than an hour finding a theme you like and move on.

If you don’t already have a network of people to point to your blog, it may seem like you are pushing content to a black hole. The first few months of this blog I saw next to no traffic. But keep at it. If you build it, they will come.

Eventually you’ll pop up in search engines and your peers will start coming back on a regular basis. Unless you have a popular flagship piece of software/hardware to your name, the growth will be slow and steady. Just be patient. In the end your blog will likely be the most important thing that identifies you.

Be Seen

So how do we start growing that blog audience? Through the miracle of social networking.

You should be familiar with some of the most famous social networking haunts in the world by now in Facebook, Twitter, and LinkedIn. If not, get familiar. These are huge, free audiences that will grow proportionally to the amount of effort you apply to them. Personally I’ve found all the good tech interactions on Twitter, but YMMV.

NOTE: I could write a whole other post on building a Twitter identity and leveraging it. Let me know in the comments if you are interested. Short version: Use Tweetdeck, WeFollow, and Twiends.

Two other places you should consider posting your work judiciously are Reddit and Dzone. Reddit obviously has everything under the sun posted to it, but useful subreddits like Programming, Technology, Android, etc… are important to visit. DZone is kind of like a standalone version of Reddit’s programming subreddit. If you put links to interesting, relevant original work up on these sites, you have the potential to drive serious traffic to your personal site(s).

Contributing to the open source community and providing raw work for feedback is a great way to catch people’s eye as well. For developers, look into creating accounts and contributing to either Github or Google Code. As a designer, check out some of the popular design communities like Forrst or Dribbble.

Be Unique

I don’t mean you have to have something outlandishly weird every time you publish content, but make sure you aren’t just paraphrasing wikipedia or SDK documentation either. The thing that is going to set you apart from every other blog in the world is your unique perspective on your chosen technologies.

That’s not to say simple tutorials blog posts are bad. In fact, they are pretty good for getting you more hits from search engines. It’s your technical, and even personal, history along with your (un)biased opinions that will give your content a feel that is distinct to you. And that’s what will give you relevance.

Talk

Now that you know where to make the connections, start engaging them. If you want people to listen to what you say, they need to believe you know what you are talking about. The best way to convince them is to have logical, spirited debate with them.

Find the talkers on the social networks, wait for or propose discussions on topics in which you have expertise, then talk shop. Be one of the people giving critical feedback on Forrst, sending pull requests on Github, or tweeting tips on Twitter.

People like developers who have a personality. The more human and accessible you are, the more likely that people will want to see what you do next.

Know the Players

Identify the key people in your area of interest and try to become part of their social network. This is a very delicate task and one that grows exponentially harder depending on the popularity of the people you are trying to get in with. You need to be interesting without seeming like you are begging for attention.

In my experience, the best route is to help them out. If you know a developer who needs testers for an alpha app, volunteer. If there’s a project out there that you had a great experience with, write a blog post about it and let the owners of the project know you wrote it. Make yourself useful, rather than just being a leech on their status.

Having an in with the core people in your area of interest carries not only the benefit of relevance by association, but you also will be on the cutting edge of what they have to offer. Advance alpha testers and new tools are often offered first to those in the social network of these key players.

Focus

Hits and visits to your site aren’t really impacted by how cohesive your content is. Subscriptions, though, the visitors who come back time after time, are. Your faithful fans come to expect a certain kind of content and can easily be turned off if one day you are posting about writing 3D Flash applications with Away3D and the next you are posting code for a packet sniffer in C++.

Don’t let this divert you entirely from one-off topics, especially if they are currently trending. Just don’t make it a habit and keep those one-offs technology related. Most people who run tech blogs that have other non-tech related endeavors tend to have separate sites for their other interests.

Also, I’m no SEO expert, but I’ve heard many times that having similar content throughout the full extent of your domain will increase your chances of showing up on searches. SEO isn’t the end all, be all of relevance, but it certainly doesn’t hurt. The more often you show up on the front page of Google, the more likely you will be viewed as an authority.

You’re Not The Best

SPOILER ALERT: You are not the best at what you are doing, and this has very little to do with whether or not your ideas get noticed or become successful. Execution, not skill, is more often than not the limiting factor for a developer’s success.

I know too well the virtual paralysis some feel when approaching a project that they think someone else could do better. Why bother when some 14 year old Japanese kind will do a better job? Why? Because chances are that Japanese kid won’t finish the project either.

The developers who have created some of the most important applications of our time were often not geniuses. They simply were very good at what they did, had an idea that they truly believed in, and executed it to completion. Not 80%, not just an alpha to play with, an actual product. Which leads me to our next vague tip…

Create Things

Pick a simple project in your field of interest and do it. Begin to end, every step necessary to make it available to your target audience. You’ll learn directly afterward that ideas are a dime a dozen because all the cost is in the implementation.

Having a completed project, no matter how simple, achieves many things:

  • You will have your name on something you can point to and immediately and show your talent and ability to execute.
  • People will start identifying you with this work, and will likely engage you more with feedback and requests.
  • Puts you in that universal developer’s lottery. You know, the one where a developer gets unexpected success based off a simple idea that just grew and grew.

Most of this is based on the idea of delivering an application, but it applies to any content: applications, books, blog posts, video tutorials, any production quality material that you would be proud to have associated with you. While we generally hate them, you as a developer need to adopt a product manager’s view in some respects, except you control the deadlines.

If you have nothing to your name yet, make your first venture very simple. Too often people get lofty ideas of creating frameworks and engines before creating one practical use case themselves. One of my favorite (recent) examples of this is Grant Skinner’s EaselJS library that resulted from his development of “Pirates Love Daisies”. He didn’t say, “I’ll develop an HTML5 and JS canvas engine then figure out what to do with it.” No, he created a game using the new technology, learned lessons along the way, then translated these lessons into code that others could leverage.

Be Interesting

I mentioned that tutorial blog posts are good for SEO, but not much else. Evangelism is great, but usually only interests other evangelists. If you really want to get a faithful audience, you need to deliver unique, interesting content.

Being controversial seems like a logical way to do this. Being inflammatory and brash is sure to turn some heads, but it can also lead to you getting black listed by the legitimate people in your target technology. So how do we raise eyebrows without being a total jackass?

I have found that inserting strong opinions into a solid technical discourse works best for me. When I write a research and comparison article, I render a decision and I put my perspective into why I chose it. Laying out the facts is very useful, but picking sides and being open to debate is what puts asses in the seats. You may not think so, but negative comments in your blog are gold. Those are the ones that generate the interesting ongoing discussion.

You need to be animated, personable, and opinionated while maintaining a staunch respect for credibility. Your audience is generally well educated and they will not stand for constant subjective statements without very strong technical backing. Think Bill O’Reilly, not Howard Stern.

Learn from Others

Get on the social networks and developer/designer communities I mentioned earlier and see what the heavy hitters are doing. Find the people that inspire you. Find the people who’s attitude and work resonate with you. Now model your behavior after them without losing your own identity.

I could elaborate on this section, but I’ll leave that to you. The interactions you have with the people that inspire you are your own. Listing mine here will never compare or seem as genuine as your own experiences. That said, here’s a shout out to a few people who have in one way or another had a very positive impact (whether they know it or not) on me and my journey to relevance in the technical community.

Work Hard

So in this 2000+ word brain dump I mentioned a lot of stuff, and I didn’t even get into the specifics of any of the content you would need to be generating. Needless to say, none of this is going to happen by itself and it’s going to take constant hard work to leverage all this info. Being relevant is not something that happens by accident.

So once you do start generating your own content, be sure to stay on top of your social connections and internet presence so your work does not go unnoticed. It is not easy work, but I assure you, over time it gets much easier.

Good luck and be sure to drop me a line if this advice helped out!

Taking Notes on Node.js using Gonzo

Gonzo

In case you haven’t heard me talking about it on Twitter, I’m creating my own markdown editor called Gonzo. If you don’t know what markdown is, read up on it at John Gruber’s (creator) blog. It was created as a way to make web based writing more readable from a writer’s perspective.

Here’s some of the highlights of the VERY young Gonzo:

  • Its open source and hosted on Github
  • Its written using Adobe Air for desktop, Flex 4, and AS3
  • The markdown to HTML parsing is done using Charles Strahan’s Showdown.as
  • Uses Grant Skinner’s StringUtils.as
  • Its 3 days old as of the publishing date of the article
  • It generates HTML as you type markdown and shows it live in a preview panel
  • Counts your words for those web writers trying to hit quotas

Test Run

Last night I took Gonzo for its maiden voyage in “production.” I went to a meetup of the Pittsburgh Javascript Developers and discussed Node.js. I’ve never looked at Node.js before as server side Javascript always seemed like the avenue of a one trick pony. After shedding my preconceived notions, it became apparent that using one language throughout your entire technology stack could work miracles with your efficiency. But its young, alpha, and it changes a lot.

Rather than ramble on from a beginner’s stand point, I’ll leave you with the notes I took last night at the meetup using Gonzo. First, I’ll show you the notes as I entered into Gonzo. Like I said at the beginning, if markdown is unfamiliar, read up. Just one glance shows you how much more readable and editable it is than typical HTML markup.

My Notes in Markdown

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
## Node.js

### Overview

* Server side JS.
* HTTP/TCP built in
* non-blocking, event driven, 1 thread (launches process into event queue)
* not suitable for CPU intensive work
* Node.js is alpha and changes a lot between revisions
* for unix, not Windows friendly
* everything is a callback and gets its own process
  * lots of nested callbacks
* has to run from command line, no GUI for management.
* you can use it as a scripting language like ruby or perl
  * does not have to be event driven if ran this way.
* Having it server side allows you to use JS up and down your whole technology stack

### NPM

* Node package managaer
* A lot like CPAN for perl

### Modules

* [100's of modules](https://github.com/joyent/node/wiki/modules)
* examples
  * Sizzle
      * DOM selections and traversing
  * Paperboy
      * serves static files
  * Jade
      * templating engine
  * ExpressJS
      * web framework
      * use it to deliver RESTful services
  * zombie headless browser
      * useful for testing Node driven services
      * assertions against returned data
      * DOM traversing is all custom code (why?!)
  * Coffeescript
  * multiple cores w/ web workers
  * Node Inspector
      * debugger
          * breakpoints
          * call stack
          * watch expressions
      * command line
      * runs in a webkit browser
      * based on google's v8 engine

### Basic Server

  var http = require("http");

  http.createServer(function (request, response) {
      response.writeHead("Content-Type: "text/html");
      response.write("<html></html>");
      response.end();
  }).listen(8081);

### Emitters

Emitters are used to counter nesting of code. Should probably use constants to define emitter names. Add parameters afer emitter name in `emit()` to pass to callback.

  emitter.emit('eventName', param1, param2);
  emitter.on('eventName', function(param1, param2) {
      // do stuff
  });

And now, through the magic of Gonzo and Showdown.as, we get to see the markdown translated into HTML. You can then take the translated HTML and publish it to the web, allowing it to leverage any CSS and formatting your target venue has in place. Again, notice how much more readable the markdown version is than this HTML version.

My Notes Translated to HTML via Gonzo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<h2>Node.js</h2>

<h3>Overview</h3>

<ul>
<li>Server side JS. </li>
<li>HTTP/TCP built in</li>
<li>non-blocking, event driven, 1 thread (launches process into event queue)</li>
<li>not suitable for CPU intensive work</li>
<li>Node.js is alpha and changes a lot between revisions</li>
<li>for unix, not Windows friendly</li>
<li>everything is a callback and gets its own process
<ul><li>lots of nested callbacks</li></ul></li>
<li>has to run from command line, no GUI for management.</li>
<li>you can use it as a scripting language like ruby or perl
<ul><li>does not have to be event driven if ran this way.</li></ul></li>
<li>Having it server side allows you to use JS up and down your whole technology stack</li>
</ul>

<h3>NPM</h3>

<ul>
<li>Node package managaer</li>
<li>A lot like CPAN for perl</li>
</ul>

<h3>Modules</h3>

<ul>
<li><a href="https://github.com/joyent/node/wiki/modules">100's of modules</a></li>
<li>examples
<ul><li>Sizzle
<ul><li>DOM selections and traversing</li></ul></li>
<li>Paperboy
<ul><li>serves static files</li></ul></li>
<li>Jade
<ul><li>templating engine</li></ul></li>
<li>ExpressJS
<ul><li>web framework</li>
<li>use it to deliver RESTful services</li></ul></li>
<li>zombie headless browser
<ul><li>useful for testing Node driven services</li>
<li>assertions against returned data</li>
<li>DOM traversing is all custom code (why?!)</li></ul></li>
<li>Coffeescript</li>
<li>multiple cores w/ web workers</li>
<li>Node Inspector
<ul><li>debugger
<ul><li>breakpoints</li>
<li>call stack</li>
<li>watch expressions</li></ul></li>
<li>command line</li>
<li>runs in a webkit browser</li>
<li>based on google's v8 engine</li></ul></li></ul></li>
</ul>

<h3>Basic Server</h3>

<pre><code>var http = require("http");

http.createServer(function (request, response) {
    response.writeHead("Content-Type: "text/html");
    response.write("<html></html>");
    response.end();
}).listen(8081);
</code></pre>

<h3>Emitters</h3>

<p>Emitters are used to counter nesting of code. Should probably use constants to define emitter names. Add parameters after emitter name in <code>emit()</code> to pass to callback.</p>

<pre><code>emitter.emit('eventName', param1, param2);
emitter.on('eventName', function(param1, param2) {
    // do stuff
});
</code></pre>

And finally below is the above generated HTML copied directly into my blog. The CSS that governs my blog does its work on the elements and makes it look relatively web ready. Obviously if I put a little more effort in (as I will soon), I can tailor the CSS to play well with my generated HTML. For now, though, you can see the basic formatting applied. So without cluttering your writing with HTML you can still effortlessly generate web ready content.

Gonzo Generated HTML on my Blog

Node.js

Overview

  • Server side JS.
  • HTTP/TCP built in
  • non-blocking, event driven, 1 thread (launches process into event queue)
  • not suitable for CPU intensive work
  • Node.js is alpha and changes a lot between revisions
  • for unix, not Windows friendly
  • everything is a callback and gets its own process
    • lots of nested callbacks
  • has to run from command line, no GUI for management.
  • you can use it as a scripting language like ruby or perl
    • does not have to be event driven if ran this way.
  • Having it server side allows you to use JS up and down your whole technology stack

NPM

  • Node package managaer
  • A lot like CPAN for perl

Modules

  • 100’s of modules
  • examples
    • Sizzle
      • DOM selections and traversing
    • Paperboy
      • serves static files
    • Jade
      • templating engine
    • ExpressJS
      • web framework
      • use it to deliver RESTful services
    • zombie headless browser
      • useful for testing Node driven services
      • assertions against returned data
      • DOM traversing is all custom code (why?!)
    • Coffeescript
    • multiple cores w/ web workers
    • Node Inspector
      • debugger
        • breakpoints
        • call stack
        • watch expressions
      • command line
      • runs in a webkit browser
      • based on google’s v8 engine

Basic Server

var http = require("http");

http.createServer(function (request, response) {
    response.writeHead("Content-Type: "text/html");
    response.write("");
    response.end();
}).listen(8081);

Emitters

Emitters are used to counter nesting of code. Should probably use constants to define emitter names. Add parameters after emitter name in emit() to pass to callback.

emitter.emit('eventName', param1, param2);
emitter.on('eventName', function(param1, param2) {
    // do stuff
});

Screenshot of Gonzo in Action

Gonzo in action

Summary and TODO

Right now what is shown here is basically the extent of Gonzo’s functionality. It’s very young, but I plan to develop it aggressively. After this post, all of my blog content will likely first be written in markdown in Gonzo. I welcome contributors to the Gonzo Github repository, but in all honesty, I’d wait a week or two before joining in. Its likely to change A LOT over that period of time.

I’ll end with the current TODO list for Gonzo. Please feel free to add your own idea in the comments.

  • Add ability to edit and apply CSS within Gonzo
  • More robust “project” environment to allow grouping of markdown and CSS with generated HTML
  • Spell Checker, likely via Squiggly
  • Major UI polish (gonna need help here)
  • Create Mac and Windows native downloads on the Github site

A Whole Mess of Android Helpers

Overview

In my work on my MMA fighter Android app Knuckle Head I used a lot of Android functionality that I’m sure I’ll use again. Things like JSON processing, asynchronous tasks with ProgressDialogs, and single instance Toasts are all things that will inevitably show up in future work. Because I’m just so generous, I decided to refactor them out of the Knuckle Head specific code and turn them into a Java package anyone could use.

* Clone or download com.savagelook.android on Github

 

The Classes

Its a small collection so far, but sure to grow very quickly. Here’s a list of the classes included so far:

  • JsonHelper.java - A collection of JSON handling functions. Includes Retrieving JSON from a remote URL.
  • KeyValuePair.java - A generic key/value pait class. Useful for populating Android Spinners.
  • Lazy.java - A collection of static classes for operations I don’t have a better home for.
  • ToastSingleton.java - I hate how Toasts in Android are shown sequentially. To prevent this I operate on a single instance of a Toast throughout my apps.
  • Toaster.java - A class that utilizes ToastSingleton.java and delivers Toasts with convenient static functions.
  • UrlJsonAsyncTask.java - This is a custom AsyncTask for a very common Android problem. I very often need to retrieve JSON from a remote URL, display a ProgressDialog while this occurs, operate on the data when it is returned, and then close the ProgressDialog. With this class that work is reduced down to just a few lines of code.

UrlJsonAsyncTask Example If you had only have time for a quick look, be sure to check UrlJsonAsyncTask.java. Using this class in side my Activity code reduced the line count drastically. Since I was lazy about documentation for any of this, here’s an example to reward my blog reader’s. This is straight from Knuckle Head code. You’ll notice a few other classes mentioned above are also included.

UrlJsonAsyncTask is not abstract like AsyncTask, most of the functionality has been implemented. You only need to implement onPostExecute(JSONObject) if you want to do something with the returned JSON. In order for this to work, your JSON needs to return an object formatted like this:

1
2
3
4
5
{
    "success":true|false,
    "info":"error or warning message from server",
    "data": {}
}
  • success is a boolean indication from your JSON source whether or not the request was successful
  • info on error or warning, will contain an app user friendly message that can be delivered via Toast
  • data This is the actual JSON object or array that you will operate on given a successful request
 

And this is how you would define your own UrlJsonAsyncTask. In this case I am querying my server to get a list of fighter, or the profile of one particular fighter. In either scenario, as stated in the JSON description above, the “data” attribute of my JSON is what I will pass to the target intent.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
private class FighterSearchTask extends UrlJsonAsyncTask {
    public FighterSearchTask(Context context) {
        super(context);
    }

    @Override
    protected void onPostExecute(JSONObject json) {
        try {
            this.validateJson(json); // throws IOException, JSONException

            // These 4 lines represent the actual post execute logic
            Class<?> intentClass = json.getString("info").equals("list") ? FighterListActivity.class : FighterTabActivity.class;
            Intent intent = new Intent(context, intentClass);
            intent.putExtra("json", json.getString("data").toString());
            startActivity(intent);
        } catch (IOException e) {
            // IOExceptions are custom and return JSON "info" in getMessage()
            Toaster.toast(this.context, e.getMessage());
        } catch (JSONException e) {
            // Lazy.Ex.getStackTrace(Exception) is just a simple one liner for turning
            // a stack trace into a String.
            Log.e("YourTagName", Lazy.Ex.getStackTrace(e));

            // JSONExceptions here are generally because your JSON is not formatted as
            // per the description in the comments above. We don't want to show these
            // errors to the user, so we give them a pre-defined error message to let
            // them know something went wrong.
            Toaster.toast(context, this.getMessageError());
        } finally {
            super.onPostExecute(json); // Must be called to close the ProgressDialog
        }
    }
}

After you have created your subclass of UrlJsonAsyncTask, you can execute these following few lines of code anywhere to fire your task and have a ProgressDialog pop up until it either finishes successfully or or returns an error/warning message. There’s tons of setters to customize your task. Check them out in the source code.

1
2
3
4
FighterSearchTask task = new FighterSearchTask(SearchActivity.this);
task.setMessageLoading("Searching for fighters...");
task.setConnectionParams(2000, 5000, 3); // connection timeout(ms), read timeout(ms), number of retries
task.execute(url);

And voila, you got JSON from a remote URL with a ProgressDialog assuring your users that the data is in fact loading. All of this is non-blocking so you are able to continue other operations or update the UI if necessary.

Summary

So yeah, it’s just another collection of a developer’s reusable tools for getting stuff done, this time for Android. If you do happen to peruse, or use, the code, let me know what you think. Suggestions,criticisms, and of course contributions are more than welcome.

Appcelerator Charging for Integrated Debugging. PhoneGap Doing It For Free.

Update 7/29/2011

As of Titanium Studio 1.2.0, integrated mobile debugging is now free! Get it here: http://www.appcelerator.com/products/download/

Searching for the Silver Bullet

So if you haven’t already figured it out, I’m gunning to decide once and for all on a cross platform mobile development framework. While all the Flash gurus I know are singing the praises of the latest versions of Adobe’s mobile platform, I don’t have the patience for an official release and docs to surface. That leaves me with two options among the frameworks I’ve evaluated: PhoneGap and Appcelerator.

If you are interested in my past evaluations, check out these prior posts I wrote:

Now judging by those past comparisons, it’s pretty clear that each framework has its place. It doesn’t have to be one or the other. Or does it?

I’m Only One Man

There comes a time after evaluating platforms, tools, and anything else when you have to make a decision. Especially is you are an indie developer like myself. You can end up diluting your potential impact on your target field by trying to be a jack of all trades, master of none. It turns out its a lot more effective to be a jack of all trades, master of at least one.

So I keep circling back to “Appcelerator or PhoneGap?” I’ve done the technical comparison and neither is the wrong choice in any respect. Both have incredibly intelligent people spearheading their development, great productivity tools, and continuous updates and improvements to their framework. So what does it come down to?

  • Which one do I spend the most time in?
  • Which one do I start pouring my effort into?
  • Which one do I start contributing back to?
  • Which one do I think is looking out for me, the indie developer?
  • Which one, if it went belly up today, could I continue to use and bend to my needs?

As I asked these questions of myself, I found that I was leaning towards PhoneGap. I will say, though, that this is in no small part to how strong the PhoneGap crew’s Twitter presence is. Here’s a list of PhoneGap people to know. I am a Twitter junkie (@tonylukasavage) and being able to ask questions and get near-immediate responses definitely swayed my thinking. They do, in general, with their MIT/BSD license and github’ed everything seem like they side with the developers more than their competitor in this case.

But damn are the native UI components and pure Javascript interface of Appcelerator sexy. I’m not a web developer by trade, so the pure JS appeals to me more than needing to know the finer points of the HTML/CSS/JS stack. And the tools they have are top notch. But that’s where my decision started to be made…

Making My Decision Easy

I just needed a definitive nudge in either direction really. Something the resonated with me and said, “This is the framework you should be using.” Appcelerator gave me that nudge, but not in their direction.

I just received an email from Appcelerator touting their new official release of their Titanium Studio. Its a great piece of software that allows you to create an Appcelerator project and deploy it to multiple mobile platforms. Sounds great, right? I thought so too, until I read on.

Upgrade to Titanium Indie or Titanium Professional to get a full mobile debugger.

Just for reference, that means $49/month for the Indie subscription and $199/developer/month for the Professional subscription. So at its cheapest rate, I’ll be expected to pay almost $600 a year just to debug my mobile applications. That is not something I’m willing to pay.

On the other hand, PhoneGap is currently working with the author of Weinre, Patrick Mueller, to incorporate it into the PhoneGap project. Yes, that’s right, they are working to integrate mobile debugging into their framework for free. Pretty clear to see what an OSS supporter like myself is going to like.

Cheap Bastard

I know what you might be thinking, “Damn, he’s a cheap bastard who isn’t willing to shell out cash for decent software.” Well, yeah, and I’ll bet a lot of my readers are pretty much the same way. But it goes beyond that. It feels a bit like a bait and switch.

They offered Titanium Developer as a means to developer Appcelerator projects in the past. Then they tell everyone that Titanium Studio is the future, so that’s what you need to be developing in if you want to stay on the roadmap. Then they effectively pull the plug on Titanium Developer, make Titanium Studio an official release, then start charging for what I consider to be basic IDE functionality. Seems a little uncool.

EDIT: Kevin and Scott (see comments) are right. This wasn’t a “bait and switch”. Titanium Developer did not have this functionality, therefore it is not deceptive that the official release of Titanium Studio does not either. I will miss it, but it was not at all deceptive.

Soooo…

As you might imagine, my personal cross platform efforts will be using PhoneGap. That’s not to say I won’t be involved in Appcelerator development. I still think its a great way to develop iOS based apps when you or your team is lacking in Objective C and/or XCode experience. Its fast, effective, and Appcelerator nailed the iOS platform. They just rubbed me the wrong way at a critical time in my decision making process. I encourage anyone reading this to not let my assessment make your decision for you as I think Appcelerator is a good fit for many.

PhoneGap is the answer to almost all the questions I posed in my list above. I just really like the team and the open nature of the project. Plus, it lets me sharpen my web developer chops (Appcelerator dev is not web dev) while working in my primary focus of mobile development. It’s just a very good fit for me and the guys I work with on a regular basis.

In the End

Its all up to an educated choice that plays to your personal strengths and proclivities. In this case, both frameworks kinda did. But due to an intense focus on community from PhoneGap, they are going to continue to win over developers like me. Who knows, though, I’m a cheap bastard. Maybe there’s no money in catering to developers like me.

While everyone needs to pay the mortgage, I somehow get the impression that the PhoneGap crew will be OK with it if they all aren’t millionaires. They strike me as guys who strive to maintain a resonance with developers. In in that effort, I say they have excelled.

Knuckle Head: My MMA Fighter App for Android

Get the App

* Click here to download “Knuckle Head” on the Android Market!

Overview

Knuckle Head is an app for the true Mixed Martial Arts fan. It allows you to search a database to find details on any fighter in the world, not just the UFC. In just a few touches you can search by name, nickname, or weight class to find every detail about your favorite fighters. This is not just another MMA news app. Inside you’ll find fighter images, detailed fight records, vital statistics, and other MMA analysis.

Oh, and I love feedback, so tell me what you want next!

Screenshots

In Case You Were Interested…

I’ll have some technical blog posts regarding this app up very soon. There’ll be lots of native Android development goodies to be gleaned. In addition I’m likely gonna post up some Android/Java convenience classes I’ve been using for various tasks like JSON handling, AdMob, ProgressDialogs, and more to my Github account. Stay tuned.

Handling Global Configuration in Android

The Problem

You have configuration variables and data that you want to share globally in your Android app. You want all Activities to be able to access and edit the same instance of application specific data.

Generic Solution

You could create a Configuration class loaded with static members or as a Singleton. Now you’ve got a shared, single instance of your configuration that can be accessed anywhere in your application. But there are 2 minor drawbacks to this method in the context of Android development.

  1. You now have to initialize your configuration in a separate class, in this case, your startup Activity.
  2. You’ll need to carry this new Configuration class around in all your projects.

Neither of these problems are critical, but let’s see if we can do better.

Android Solution

In Android it is possible to extend the Application class in order to store additional application specific information… like say configuration data. These additional members are then accessible in any Activity via the getApplicationContext() method.

The first step in this process is extending your app’s Application object. Android gives your app a generic Application object by default, so you may have never even had to look at this class directly. But as you’ll see below, its pretty simple to extend.

SampleApplication.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class SampleApplication extends Application {
    private String mStringValue;

    @Override
    public void onCreate() {
        // Here you could pull values from a config file in res/raw or somewhere else
        // but for simplicity's sake, we'll just hardcode values
        mStringValue = "SavageLook.com";
        super.onCreate();
    }

    public String getStringValue() {
        return mStringValue;
    }

    public void setStringValue(String value) {
        mStringValue = value;
    }
}

As you can see above, extending the Application class as SampleApplication is quite simple. You add class members for each bit of configuration data you would like to share throughout your application. In this example, we are simply saving a String value (mStringValue) that can then be accessed and modified in any Activity in SampleApplication.

After you’ve added your members and any necessary getters/setters, you need to override the onCreate() method. In the onCreate() method you can then initialize your class members with your configuration data. You can do this any way you want. To keep the example simple, I hardcoded the configuration value (mStringValue), but I commonly store configuration data in JSON files in res/raw and load them into my extended Application object. I won’t get into those details, though, as that will likely be a whole other blog post. Make sure you call super.onCreate() when you are finished.

NOTE: It’s not necessary to initialize your members in the onCreate(). For application-wide configuration data you would likely always do it in onCreate(), but you are technically free to manipulate the extended Application object anywhere in your app code.

AndroidManifest.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.yourdomain"
      android:versionCode="1"
      android:versionName="1.0">

    <!-- Android 'uses' elements... -->

    <application
        android:icon="@drawable/icon"
        android:label="@string/app_name"
        android:name=".SampleApplication">
        <activity android:name=".SampleActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

The final modification to make our Android app use the new SampleApplication class is setting it in the element of the AndroidManifest.xml file. The only change we make to AndroidManifest.xml is adding the android:name attribute to the element. Just add this attribute and set it equal to the name of your extended Application object, in this case SampleApplication.

OK, so now your app is using your new SampleApplication class. How do we access the stored data in its members? See the basic usage below.

Sample usage in any Activity

1
2
3
4
5
6
7
8
9
10
11
12
13
public class SampleActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        SampleApplication sampleApp = (SampleApplication)getApplicationContext();
        String localStr = sampleApp.getStringValue();
        // perform operations on localStr
        sampleApp.setStringValue(localStr);

        // The rest of your Activity code...
    }
}

All you have to do is call getApplicationContext() and cast it to the type of your new Application object (SampleApplication). The resulting SampleApplication object can now be used the get/set any of the members you defined for it in SampleApplication.java.

Summary

Now you have a solid, Android native way to share data globally in your app code. While I’m a big fan of portable solutions, I feel this Android specific one is worth to have a clear distinction between the onCreate() of my Application versus my Activities. Hopefully this walkthrough was clear because this is something you will likely do very frequently when developing Android apps.

One final note. I can already envision some lazy developers’ minds churning, “I can use this instead of Intent extras!”… Don’t! Intent extras have a specific interaction context which is important not only to functionality, but also to readability of your code. Don’t undo this by just feeding them into the global Application object. Extending your Application object is a complement to Intent extras, not a replacement.