A programmer’s attempt at marketing

I’ve always believed that if you create an amazing app people will find you. While I still think that’s true, what if you simply don’t have the time, resources or ground breaking idea to create an amazing app. If you’re just experimenting with a new framework you might be limited to creating just ok apps. Apps which may offer a novel experience but don’t have the same level of polish as apps by big name publishers.

This is where I found myself a few months ago. I’d like to share with you my successes and failures thus far. If you have suggestions for things to try in the future please post your suggestions in the comments below.

First a brief explanation of the app. It’s called Music Maker Pro and is available for 99 cents in the Apple App Store. It enables you to easily create music by tapping a few boxes. In an effort to increase awareness of the app I created a free browser-based version which you can try at http://mscmkr.com.

On to the traffic… the graph shows the number of new users per day over the past three months to both the free and paid versions. It can be roughly divided into four sections.

Stats

  • Paid advertising (blue) To get started I used a combination of AdMob and Facebook ads. While paying money definitely got me traffic the conversion rates were way too low for this approach to be profitable.
  • One big tweet (red) My next tactic was to try to get well-known people to spread the word. Scott Hanselman was kind enough (thanks again Scott!) to share the link on Twitter and Google+, the results speak for themselves.

  • Letting time do it’s thing (yellow) Here again the results speak for themselves. Doing nothing achieves nothing. I may have posted to the app’s Facebook group or sent some random emails but I clearly didn’t do anything to move the dial much.
  • The Chrome Web Store (green) I wasn’t expecting much but this has turned out be my best move to date. The app is now available here and so far has generated decent growth in traffic.

As I opened with, I think a key determinant of the stats is the app itself. While mine isn’t total crap it probably won’t win any design awards either. The competition in the app market is pretty intense. With the advent of in-app purchases, publishers can spend millions of dollars developing apps which they release for free.

Any time I read a random article on a developer’s download stats I’m always hoping to get a dollar amount. On average I sell about one or two apps a day. While it’s not a lot it pays for the server costs and definitely beats my last two mobile apps for which I’m still in the red :/

AutoComplete added to Github

I’ve been spending much less of my time these days coding in Flex and as a result haven’t done much work on the AutoComplete component. I realize many people (including myself) still use the component in production applications so it’s important that it continues to be maintained.

I’ll be the first to admit that I should have done this a while ago, but… I’ve finally added the source code to Github.

https://github.com/hillelcoren/flex-autocomplete

If you resolve any bugs or implement any features please send me a pull request and I’ll merge in your changes.

Wrapper for JavaScript console.log

One of the best ways to debug web applications is to use the console.log() function. The catch is while it works in Chrome as well as Firefox (with the Firebug plugin) it causes errors in IE.

Here’s my version of a very simple wrapper function which:
– Prevents errors in IE
– Supports the console functions I regularly use (log, info, warn and error)
– Allows using %s to substitute parameters. ie, log(“length is %s”, foo.length)

window.M5 = window.M5 || {};

$.each(["log","info","warn","error"], function() {
	var name = this;
	M5[name] = function () {
		if(!window.console) return; // prevents errors on IE
		console[name].apply(console, arguments);
	};        
});

// sample usage
M5.log("My test log message");

Note: this requires jQuery and uses the M5 namespace (which you may wish to change for your own application).

Google Sync End of Life

Google’s been cleaning house lately and as of January 30th, 2013 most Gmail users will no longer be able to sign up for Google Sync.

When first setting up a Gmail address on an iPhone one would assume the vast majority of people would choose Gmail from the list below.

Add Email Account

Turns out if getting your emails as quickly as possible is important to you the better choice is Microsoft Exchange. By setting up Gmail as an Exchange account (using Google Sync) you’re able to configure your emails to be pushed rather than fetched.

The key point here is that Google Sync will continue to work if your phone is configured to use it before January 30th. If you haven’t already done so, now’s your chance. It’s worth noting that you could also use the Gmail app but personally I prefer Apple’s built in app.

Ruby on Rails from the perspective of a Flex developer

A little while ago I decided to take a look at Ruby on Rails. I built a small application and thought it may worthwhile to share my impression of the framework.

The great thing about Rails (and most other MVC implementations) is that assuming you’ve worked with MVC before you already know how it all fits together. The main challenge we face as coders is managing complexity, the MVC pattern is a perfect fit for Web based applications.

While Rails is similar to other MVC frameworks, it certainly has its unique aspects. One of my favorites is the concept of migrations. Migrations allow you to tie your database changes directly to your code changes. It becomes even more useful when used with Capistrano (a incredible deployment tool). In most other projects I’ve worked on I’ve needed to keep track of my database changes, when it’s time for release these changes are then run on the production database. Migrations give you a formal way to solve this problem. In addition they make it possible to roll back schema changes if for example you decide to back out a deployment. With Capistrano, deploying to production just takes a single command and rolling back is just as easy.

Another great Rails feature is ActiveRecord. This is essentially an Object Relational Mapper (ORM) which means you don’t need to write SQL queries to manage your data. You can simply manipulate objects and ActiveRecord handles updating the database. Since Flex apps can’t directly manipulate the data in your database, using Rails as a server-side technology with a Flex front end works really well. Additionally, there are many Gems (Rails plugins) available which enable you to (among other things) extend the ActiveRecord approach to other datasets. For example, the Gmail and SugarCRM gems enable you to access the respective datasets with just a few lines of code.

Finally, the Rails framework provides a ton of useful functions for everyday tasks. A good example of this is the pluralize function. It takes a string an determines the correct grammar depending on the number of items. ie, “1 record” vs “2 records”. Here’s a simple ActionScript function to provide a similar functionality, although it won’t be able to handle a 1 person/2 people.

public static function pluralize( string:String, count:int ):String
{
	string = string.replace( "?", count );
	return count == 1 ? string : string + "s";
}

// sample usage
StringUtils.pluralize( "? record", data.length );

The Ruby language itself is entirely object oriented which is really nice, but I struggled to switch back to a dynamic language. Years ago I loved the flexibility it provided but I’ve grown accustomed to the ease with which I can refactor variable/function names in Flex. It’s said that static languages just check that your code is syntactically correct while dynamic languages with unit tests can check that your code is logically correct. This may be true but I’m willing to bet there are quite a few Rails projects out there without many unit tests.

The main problem I ran into was actually related to hosting. Rails performance has come along way but the challenge I faced was the start up times. The hosting provider I used (I imagine many are the same) would shut down the Passenger server if the app wasn’t used for 5 minutes. Start up takes a good couple of seconds which meant for a site with little traffic it appeared to have horrible performance. I worked around this by having a cron access the site every couple of minutes but this obviously isn’t ideal.

Rails alone clearly can’t complete with Flex in terms interactivity but when paired with JQuery UI or another JavaScript framework there’s hope. I believe we’re still years away from an HTML equivalent to Flex but only time will tell… who knows, maybe the Falcon JS compiler will one day take flight.

Secure password primer

More and more these days I’m getting “I was hacked… ignore my emails” emails from friends and family (I won’t get into the inherent paradox which exists here). I thought it might be helpful to write a short post explaining the rules to follow to help prevent this from happening.

  • It can’t be too simple
  • It needs to be unique

There are two main ways by which evildoers get your password: they try to guess it or they steal it. Choosing a complex password makes it far more difficult for your password to be guessed. Here’s a good site with instructions on choosing a password as well as a great xkcd comic on the subject.

The problem we’re now faced with is making sure it’s unique. Although you can probably trust Amazon to securely store your password the same may not be true of some other random site you use. If they get hacked (and they didn’t store your password encrypted) bad guys now have your email address and password and will try it on other sites. A good password is harder to remember than “1234” so it’s clearly a challenge to remember a unique password for every site you use.

Here are two ways around this problem: You can use a tool which will store your password for you such as lastpass. Although they offer browser plugins to make entering your password easier you should keep in mind that this can be inconvenient when using a friend’s computer or Safari on your iPhone. The other option (which is especially useful for sites you rarely check) is to use a random string of characters and simply use the “forgot my password” feature when you need to log into the site.

Latest project at work

For the past 8 years I’ve had the great pleasure of working for M5 Networks, a market leader in cloud-based phone systems (if your company is looking for a new phone system definitely get in touch).

One of the many great features we provide is the ability to create call flows to efficiently direct incoming calls. This tool provides a visual display of the call flow and allows the user to easily make changes.

The application makes extensive use of my AutoComplete component, as well as the excellent Flare visualization library.

In my opinion this is exactly the sort of application where Flex excels. I’m hopeful that the Apache Flex project can help keep Flex as a leading choice for web-based enterprise applications for years to come.

Flex AutoComplete: Version 1.2

I’m just wrapping up a Flex project which used the component extensively. Along the way I noticed a number of reasonably serious bugs which this update fixes.

Latest version

  • When using the component as an item renderer the sizing is sometimes messed up
  • Prevented a toolTip from appearing when selecting an item
  • Resolved tab focus issue when using the component in a Flex 4 project

One other change in this release is that all private methods and properties have been changed to protected. Minor changes should no longer require using the sourecode.

Best,
Hillel

Flex Error #1009: Cannot access a property or method of a null object reference (update)

A couple of years ago I wrote a post discussing the Flex error #1009 (cannot access a property or method of a null object reference). If you’ve done any serious amount of Flex coding I’m sure you’ve run into this error a number of times.

While there are a few possible causes, the post discussed how a lack of understanding of the Flex component creation lifecycle could be a possible culprit. While everything in the post is still technically accurate (for Flex 3) I find that I often just use bindings if I need to set a property of a child component.

So… here’s the fourth way to solve the problem (at least for simpler use cases).

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">

	<mx:Script>
		<![CDATA[

			[Bindable]
			public var buttonLabel:String;
								
		]]>
	</mx:Script>

	<mx:Button id="button" label="{ buttonLabel }"/>

</mx:Canvas>

I realize this is pretty obvious to most Flex programmers, I just wanted to clarify for people who are new to Flex and are finding the old post.

Flex Gotchas

On the whole, one of the aspects I like most about Flex is that it generally works the way you expect it to. That being said there are definitely certain things which don’t quite work as expected.

Corner Radius

This is actually what inspired me to write this post. I’m a fan of rounded rectangles (add a vertical gradient and a drop shadow and you’ve got a classic Web 2.0 look). I’d expect this to do the trick.

<mx:Box backgroundColor="#888888" cornerRadius="8"/>

However, to make it work you need to set the borderStyle property

<mx:Box backgroundColor="#888888" cornerRadius="8" borderStyle="solid"/>

Hand Cursor

A similar example is when trying to show a hand cursor. I’d expect this to work.

<mx:Label text="test" useHandCursor="true"/>

However, you need to use the following

<mx:Label text="test" useHandCursor="true" buttonMode="true" mouseChildren="false"/>

SWF Caching

This is more of a Firefox bug, however if you rely on the browser to handle caching the SWF (and updating when a new SWF is created) you’ll run into problems in Firefox. The best solution I’ve found so far is to convert the html wrapper file into a PHP script (any scripting language should do). You can then add the following to the SWF name.

?checksum=<? echo md5_file("__SWF_file_name__") ?>

Binding

I’ve written about this before but it’s caused me enough trouble that it’s worth repeating. If there are null errors inside of a function used in binding the Flash player will swallow them. It needs to do that as binding expression will often have null errors (ie, if you bind to person.name and person isn’t yet set). However, this can be very confusing.

Copying Objects

A really useful function is ObjectUtil.copy(), it will make a deep copy of your object. However, in order to use it you need to first register any classes which your object is composed of. Here’s the code I use.

for each (var classRef:Class in [ Class1, Class2, etc... ])
{
	var className:String = getQualifiedClassName( new classRef()) ;
	registerClassAlias( className, classRef );
}