Thursday, March 22, 2012

Cowboy + ErlyDTL

This is a continuation of part 1 so I'm going to assume we're starting where we left off there.

Now that we have a Cowboy server that can handle static pages, we need to set it up to handle dynamic pages.  In comes ErlyDTL.  This is basically going to be the same as OJ's tutorial but for Cowboy instead of webmachine.

ErlyDTL Install
Change your rebar.config to include the ErlyDTL dependency.
Run ./rebar get-deps compile to make sure that step worked.

Make a page controlled by code
Modify src/simple_server_http.erl to add a path and handler name to the dynamic page you're creating in dispatch_rules/0.  In this case, requests for the 'pony' resource ( should be handled by simple_server_http_pony.
Create src/simple_server_http_pony.erl
Create templates/mylittlepony.dtl

Remove the previous release, compile, generate, run.
Go to  Dazzleglow is everyone's favorite pony.

Take in user input
If only the world were so simple that we could just create answers...  The following shows how to deal with GET/POST parameters so we can take input from those pesky users.

Create a new dispatch rule and handler for a page called captainflint.  I'm going to assume you know how to add a dispatch rule to src/simpleserver_http.erl at this point.

Go to  Thar she blows.  Now you have a working example of how to access GET and multi-valued POST parameters.

Monday, March 19, 2012

A very basic Cowboy setup

I'm new to using Erang in a "real" way, but I've been wanting to use it for a while.  Looking around at the Erlang landscape these days, I don't feel bad for having waited four+ years.  Some projects have come onto the scene in the last couple of years that make development in Erlang a practical reality for those of us who don't have the time to develop everything from first principles.  Basho's webmachine was very close to being my web server of choice, but I needed web sockets so Cowboy seemed like a better choice than cobbling together my own webmachine/web socket router.

For today's deposit into the Google karma bucket, I'm going to run through the setup for a super duper simple Cowboy web server so you can move past the plumbing stage faster.  I started from the BigWig project and stripped stuff away until I had a web server that would serve static pages and 404s.

Pre-requisites (Blogger, why do I have to bold this instead of just selecing an <H2>?)
Erlang (R15B), rebar, Unix-y OS (Mac OSX in my case)

Set up directories and copy over rebar binary

Create rebar.config in your project directory

Run rebar commands to create a basic server and release.  It's easier to name everything the same as the project directory than it is to figure out what to change in the configs.

Modify rel/reltool.config so that lib_dirs points to the directory that contains the src directory - ["../.."]

Make a simple web server
Add 5 new files and modify one of the generated files.  I think there's a way to have rebar generate all of this, but I'm not going to bother figuring that out until I've got a better sense of what all I want to have generated for me on future projects.

Create src/simple_server.erl

Create src/simple_server_http.erl

Create src/simple_server_http_catchall.erl

Create src/simple_server_http_static.erl

Create priv/html/index.html

Modify the init/1 function in src/simple_server_sup.erl to include your HTTP handler

Build and test
The following will pull down Cowboy, compile all your files, and generate a release that you can run:
./rebar get-deps compile generate

From the rebar tutorials I've seen, you should be able to call:
./rel/simple_server/bin/simpler_server start

This call returns without error and if you look at your processes it looks like something's going on, but there'll be nothing for you in your web browser.

Instead, call the following the start up your server:
sudo erl -sname simple_server -pa $PWD/ebin $PWD/deps/*/ebin -boot start_sasl -s simple_server

Make sure to call it with sudo since we have the port set to 80.  If you set it to something like 8000 you don't have to call it with sudo.

Open up in your browser and celebrate.  Open up in your browser and celebrate some more.

Yay, now we have a lame server.  Next up, we need to add templating and a datastore to do more interesting stuff.  See part 2.

Saturday, March 17, 2012

In-app purchases and children's apps

At the AppNation conference in SF last December, the conventional wisdom of the talks seemed to be that best business model for app developers is free plus in-app purchases.  This makes a lot of sense for regular apps where the user is also the account owner.  Free to get a lot of people to try your app, in-app purchases to present the buying opportunity when your users are in the buying mood.  Brilliant.  But what if the user isn't the account owner?

This model breaks down for children's apps because the app proves its worth to an advocate and not to the buyer.  Even the best kid-sized con-artists advocates have a hard time convincing the same parent to buy an add-on ten different times.  It's better to package those ten things up into a single purchasing decision (think "pro" version) and ease the burden on your little salespeople.

Friday, March 16, 2012

Thoughts on the market for education/children's apps

(Originally drafted this in October 2011. Writing about COPPA got me a little hot under the collar so I took a break to cool down and then things got busy. Figured I should finish this before posting new stuff.)

Ran into a question on Quora that got me thinking. "Why is there a lack of innovation in educational technology for school-aged children (compared to high school & higher ed)?"

As an app developer, I'm going to interpret this as "Why are there cool apps for high school and higher, but not for elementary school?" The four reasons I see as the cause for this situation can be summarized as money, demographics, mix of skills, and legal.

Independent app developers have, in the words of Captain Malcolm Reynolds, "a powerful need to eat sometime this month". To this end, developers will gravitate towards app categories that make the most money or have the perception of making the most money. On the perception side, a search for 'app developer success stories' shows interviews with developers who made a pretty penny off of games, entertainment, games, utility, and games.

On the real money-trail side, a look at some numbers from Distimo's June 2011 report and's App Store Metrics from late September 2011 show that the money just isn't there.

Distimo's numbers show a standard power law distribution with a couple of categories accounting for a vast majority of the downloads. Games and Entertainment account for about 65% of the free app downloads on iTunes and 75% of the paid app downloads in the US. Books and Education account for somewhere between a low single digits percentage share to 'too small of a line to be visible'.

The disparity in download numbers could be attributed to a disparity in apps available to download. Maybe there are more games being downloaded simply because there are more games available.'s numbers show that this isn't the case. Games represent 17% of the apps available while commanding 60% of the downloads. Books and Education represent 21% of the apps available while only garnering 2% of the downloads combined.

Money attracts attention and talent. The more people you have staring at a problem, the more likely someone will come up with something cool. That's not to say that those of us working in the education app space can't innovate. By the numbers, it'll just take us more time to saturate the ABC and periodic table sides of the spectrum and start filling in the middle.

The number of developers might be proportional to the number of apps (and therefore there might be a lot of education developers even though there isn't as much money in it), but I suspect this is not the case. My guess is that many game development shops these days have multiple full-time people working to produce a game from a game designer, a sound designer, a graphic artist, and multiple developers. Most apps in the book and education categories are probably from much smaller one and two person operations. The description for one of the top flashcard apps even says that the developer only works on the app part-time as hobby. You don't have to be full-time to make a great implementation of a new idea, but the odds of creating something great are probably in favor of those who spend more time working on it.

There is a natural tendency to work on problems that you see. App developers are fairly young on average. Most probably don't have kids and those that do probably have very young children -- thus the plethora of ABC and 123 apps. Other developers can probably only think back as far as high school. It's hard to think of a time before you knew algebra and how you learned it.

Mix of skills
Producing a quality education app is hard. In addition to development skills, you need skills in graphic design, sound effects and composition, user experience design, and teaching. That's a lot of different skills to bring together. With games, you can play with them and pick apart what made things fun for you. With educational apps, there aren't as many examples to learn from and it's harder to analyze them because you already know what they are supposed to teach you.

Developing apps for users under 13 years old requires attention to COPPA, which restricts innovation and use of standard practices without offering any real protection for children. With COPPA, you can't associate an installation of the app with any sort of identifier and no custom messages are allowed.

With the way they've crafted their no custom message rule, there's no free form text allowed anywhere. You can't have a 'name' field where they could put in their full name, but you can have fields for first name and last initial which makes no sense because there's nothing to stop them from just putting their full name into the first name field. By the letter of the rule, kids are not allowed to share their art directly from their kid-friendly art app. They'll just have to hit the home button and open the email app and attach the image from there. The rule does nothing here but throw up a usability speed bump.

Here are some of the things that you can't do without some sort of identifier:
  • gather anonymized stats to see how users are interacting with your app and where they might be getting stuck
  • validate in-app purchases on a server (which would help defend against piracy and allows you to deliver content on-demand instead of shipping really large binaries)
  • allow people to share content without having to create yet another set of account credentials
  • auto-magically sync content bought through other authorized channels such as your website or a device on another platform
Some developers are okay with working under the assumption that they won't get in trouble implementing some things that technically violate COPPA as long as they're not violating the spirit of it and using the gathered info for aggressive direct marketing. I'm not. The whole idea that I might be trying to bring joy and learning to kids one day and get slapped with a $50k fee the next day is nauseating. It's an extra hardship on top of the struggle to be profitable while doing good.

So why aren't there better educational apps for elementary school kids? It's hard, you don't end up with something cool that you can show off to friends, there's no money in it, and you might get in trouble with the government.

Thursday, March 17, 2011

iOS Linebreak Fun

Learned something the hard way today.  You'd think that the order in which properties are set shouldn't matter even in weirdo Objective-C land, but things are different over there.

The following will wrap long button text, but limit it to two lines.

button.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
button.titleLabel.numberOfLines = 2;

The following will wrap long button text all over your image and outside the bounds of your button.  You'll be scratching your head for a while wondering why the numberOfLines property doesn't have any effect.

titleLabel.numberOfLines = 2;
button.titleLabel.lineBreakMode = UILineBreakModeWordWrap;