Race to the Bottom: iPhone App Store Pricing

I’ve had a notion for some time that the price wars on the app store may be detrimental to the community. I know I’m not alone in this feeling, and have found others online who would agree. Finding like-minded developers isn’t my goal. I’m wondering when, or if, the App Store will begin to resemble something a little closer to desktop boxed software prices.

I think it would be wrong to assume that mobile apps will reach the cost of boxed software. However, I do believe we’re shooting ourselves in our proverbial feet by pricing perfectly good applications at free or even $0.99. Admit this – comparing a $0.99 app to a $2.99 one, both with similar features, ratings, and quality user interface, which one are you more likely to buy? If you were the guy selling the $2.99 app, wouldn’t you feel compelled to lower your app’s price even just a little? I mean, some money is better than none?

Assumptions

You’re going to make a few assumptions, be it good or bad, but one way or another they will affect your sales. These probably fall into two or three areas, 1) lowering your price will communicate better value; 2) lowering your price will increase sales; 3) more sales means more profit.

Better Value?

That’s open for debate. Customers may think they’re getting a great app for cheap (high value), or they can see a lower price (whether your are lowering the price or setting a low initial offer) and think nothing of it because everything else in the category is priced roughly the same.

Increased Sales?

This might also be true. It almost goes without saying – people can buy more cheap apps on the same budget than pricey ones. I’ll give you a +1 for remembering the concept of supply-demand curves you learned in your high school econ class. There is, unfortunately, a wrench thrown into your increased sales equation – anecdotal evidence points to the best sales occurring right after launch and eventually falling off after the 60-day mark. We’re working with a limited time frame to make the most we can.

More Sales, More Profits

All things being equal this becomes a matter of math. Cutting your app’s price in half means you need to double sales to make the same amount of money. Do you think you can do that? Realistically? In the 60-day window where most developers see the largest chunks of their sales?

Closing Thoughts

I’m going to finish up with one thought that should bring this full circle. Before pricing your app consider the cost of the downward price war. You may make more sales, but you won’t make a decent income off of it. Should this trend continue, our users will become spoiled enough that they will hardly tolerate higher priced apps unless they are truly unique and worthwhile. This price war is only hurting ourselves and something will have to change or the App Store will end up a wasteland of low-quality apps because the true developer dollars will go elsewhere, thus making the iPhone/iPod Touch platform much less appealing for everyone.

Compile Multiple App Versions in XCode

Well on my way to becoming comfortable with Objective-C and Cocoa, I came across the need to create two versions of an app I was working on – one a “Lite,” and the other a full version.

Branch merging scares me

Like any good developer, I use source control management to keep tabs on my development cycles. This time, being no different than any other, I dutifully created a new branch for a lite version of my application once I completed the critical features milestone. Being one who doesn’t have a lot of use for branching in most projects, I was reluctant because (be honest here) the notion of merging back and forth between the lite and the full branches was a painful one.

Ok, I know – merging shouldn’t be that big of a deal, but what about this scenario? I’m adding some features to the full version that I decide I want to port back to the lite. Auto merging isn’t going to work (we can give the lite app all the same features of big brother), but neither am I so keen on going line-by-line every time I make a change. Cry me a river, right? Well, no. Actually, the solution is easier than that.

Enter: Compiler flags

I don’t know when I first learned about it – it could have been in my early programming days when I was learning about C – but I’ve always had ideas about compiler flags in the back of my head… very dim ideas. Look through Cocoa demo apps (check your Cocoa docs) and you’ll see several that have lines of code that seem to point to something specific:
#if defined(LITE_VERSION)
//do something here
#endif

That’s a compiler flag. That’s the key to getting your lite version separated from the full version at compile time (or runtime, or whatever, depending on your need). Using those compile flags you can separate specific portions of code for one version of your app to another.

I’ll save you the dirty details of how you do this. Instead, head over to Junda Ong’s blog.

My First Native iPhone App

It’s Thanksgiving Day weekend – one of my favorite of the year – because it gives me the chance for some nice, quiet R&D time without the pressure of clients or projects asking to get things done. This week I finally made it through enough of my Objective-C/Cocoa/iPhone books that reading further felt like I was just going over more specialized use cases. For now I don’t foresee the need to have covered every topic before I get started – the basics are covered.

Of the app ideas I had going into this weekend, I chose the simplest (training wheels – crawl before I can walk, right?). It’s a Tabata timer for interval-based workouts. Nothing too special. The basic functionality is there, but I want to pretty it up and add a couple features before submitting it to the app store. I doubt it’ll really make me any money, but I did it for the exercise, not for the big bucks. I’ll post screenshots and links when it’s finished/up.

Installing PEAR Libraries Locally

[I started this post quite a while ago and forgot about it. Here it is finished. Hopefully you find something useful here]

I’ve had a few projects already where I could really use some PEAR libraries but not sufficient enough access to the server so I could install them in the system-wide PEAR include directory. I went searching for an easy to manage way to package specific PEAR libs along with apps I was building and installing for clients – something that would work without access to system-wide PHP/PEAR setup, and even in rare cases where I couldn’t write outside the document root.

First place to at least read through is the documentation. I’m going to assume you already know the basics of PEAR.

This summary will discuss the FTP method, as it seems applicable to more situations. For me – I keep my sites under version control so I need to be able to perform a local install that I can commit to the repository and either export or update on my various server environments.

Tools:
* Terminal or command-line (CLI)
* CLI version of PHP
* CLI version of PEAR

Steps (code follows)

  1. Create a directory where you want the PEAR libs installed. Note: PEAR will create a directory named pear in the location you specify.
  2. CD into that directory.
  3. Create your config file for your local environment (probably won’t be needed on external servers unless you plan on installing from there, in which case you should create a separate config file for each site).
  4. Install and update packages.
  5. Update your app’s include paths.

The Code:

  1. Create your config file in the PEAR directory from step 1, above. Absolute paths, absolutely!
    %> pear config-create /path/to/app/htdocs/includes /path/to/app/setup/pearrc

    The first path is the location where you want the files. The second path is the location where the pearrc file is located. I usually put the PEAR files in an includes directory within the site’s document root, just in case a host or client I’m dealing with doesn’t have write access in higher-level directories. It’s best to keep the pearrc file outside of the webroot, or deny access to the file via Apache’s Allow/Deny directives.

  2. To run PEAR commands on your local install, you will need to use the following format
    %> pear -c /path/to/app/setup/pearrc [command]

    (otherwise you’re likely working on system-wide changes – doesn’t help you when it’s time to deploy to the server). An example,
    %> pear -c /path/to/setup/pearrc install File_CSV_DataSource

  3. Set your app’s includes path to search in the PEAR directory:
    set_include_path(DOCUMENT_ROOT."/includes/pear/php".PATH_SEPARATOR.get_include_path());

    Change as needed.

That should do it. It’s a basic introduction, but if you already know how to use PEAR, you’re already 95% of the way there.

 

N00bs are OK Too

Here’s a little commentary over at CakeBaker on people apologizing for being a newbie.

On mailing lists or in private mails I sometimes read statements like “I am sorry, but I am a newbie” or “Sorry for this newbie question”. And I always wonder why do those people apologize for not being proficient?

I think the apologies come from the fact that most communities has their fair share of snarky members. Case in point: I was on IRC the other day to ask a question about a new language/framework I’m learning… it was a REALLY easy answer for the experienced developer, but for whatever reason I wasn’t sure if I fully understood the concept. Among the types of responses I received, most were fairly typical:

  • A couple genuinely helpful answers
  • The “What do you mean you don’t get it? How can you NOT understand?” type response.
  • That I should stop what I’m doing now, close the book I’m trying to learn from, and read through another book on a different subject. In this case it would be like (not the actual case) being told to stop reading the Agile Development with Rails book in favor of reading Programming Ruby 1.9.
  • The non-response – nobody responds to your request for help. Mind you, I do a lot of extra work to make the barrier to helping me as small as possible.

After my experiences, I’m not surprised that people apologize for being noobs. It’s embarrassing to be made to look like a fool in public, especially when you have to ask for help because you can’t get it on your own. Now of course, I have less sympathy for people who don’t read the documentation and at least try, but if you’ve done that and it’s still a cloudy mess in your brain, ask away.

Using Pinch Media Analytics in PhoneGap

Getting close to finishing up an app for a client in the coming weeks, my business partner and I decided it would be a good idea to include some analytics code so we could track how people are using our application. We ended up using Pinch Media’s Analytics to do our tracking. It came down to this: their code is REALLY easy to implement, and they provide us with just enough information to satisfy our curiosity. I think one of the biggest draws is that it records information regardless of the user’s online status – meaning offline app usage information is stored to a small database and then uploaded once the user reconnects. Had we used a web-based solution, which would have been natural given the nature of PhoneGap (the underpinning of our application) being UIWebView, we would have missed out on some details without considerable work-arounds to cache data as Pinch Analytics does.

Because PhoneGap is essentially a single view application that displays web pages, you are a bit limited with the extent that you can integrate Pinch Analytics out of the box… unless you use javascript callbacks to Objective-C within PhoneGap. That’s not the point of this post. The point is that you just need to follow Pinch’s instructions and you will have analytics data reported back to you within a few hours.

Moving forward, I’m likely to investigate some of the finer points of creating my own PhoneGap callback functions so I can embed Pinch Analytics Beacon methods, which are nice little ways to record information about discreet actions taken within your app – recording leader board views, for example.

PhoneGap Up To Speed

I recently ran across some major performance problems with a jQTouch app running in PhoneGap. Some of the symptoms included long pauses on touch events, non-responsiveness, and laggy transitions.

Brian LeRoux (Nitobi/PhoneGap), Jesse McFayden (Nitobi/PhoneGap), and David Kaneda (jQTouch) were the stars looking into this issue. Ends up Jesse found where the Accelerometer was taking a 40Hz sample rate and sending the data to a callback. The solution is to just disable Accelerometer use – either in the plist or, as I did, comment-out all the accelerometer bits. Likewise, I removed location functionality, as this app in particular doesn’t need it.

You can read Jesse McFayden’s post here. And if you’ll excuse me, I have an app to finish…

ReadOnly Form Elements

Here’s a quick note for the frustrated:
When setting the readonly parameter on a form element via javascript, make sure you use a capital “O” as follows:
elem = document.getElementById('myInputElement');
elem.readOnly = true;

Why it took me so long to find that out, I have no idea why. Most forums threads by others seem to think the disabled parameter is the best way to go. Actually, the sheer number of people suggesting that makes me think it’s a bad idea – just following the crowd. This is why readOnly might be the right option: You’re still allowed to post the form value, but the user isn’t able to change what’s inside the box. When using disabled *nothing* gets posted from that element. So if all you want to do is prevent a user from editing the value of a form element, use readOnly. If you don’t want that value posted, then go ahead and use disabled.

Enjoy!

Backups to Amazon S3 the Easy Way

I was looking for a simple solution to backup my newly constructed server to an off-site location in case something were to happen. I don’t mean I lost a file… more like catastrophic hardware failure, fire, water damage, physical damage, and even theft!. Local backups really are best, and I don’t plan on abandoning them any time soon, but in the case of the one in a million chance where something like this occurs, there’s a high likelihood that everything might be lost.

Enter Cenolan.com: How to: Incremental Daily Backups Using Aamazon S3 Duplicity. It really is pretty easy. Just one thing: besides installing Duplicity (also required a few other dependencies), I had to install Python-boto: yum install python-boto

You may also be interested in doing regular backups of your MySQL database (from HowToForge.com)

Adding the Fedora Install DVD to Your Yum Repo List

I recently performed a major upgrade on my file server this week. It was a lot harder than it should have been, but that’s only because my Linux Foo can only go this far. Two to three re-installs later on the new hardware it was getting old, so I told the Fedora installer to just do the base package and I would worry about the rest later.

Worry is not my middle name, but frustration might be. For reasons unknown to me I thought I could just do an “upgrade” from the installer. Wrong. Then I thought maybe I could boot normally, insert the DVD, and I could then select it as a package source. Wrong. Download all those packages I missed the first time around isn’t an option on slower-than-molasses connection I have at home. So I did what any other self-respecting nerd would do – turn to Google.

The trick lies in the Yum Repos list, located in /etc/yum.repos.d/fedora.repo

Check it out. Normally you have three entries: Fedora, a Debug branch, and a Sources branch. The primary Fedora branch configs look something like this (I’m using Fedora 10 in my example) :


[fedora]
name=Fedora $releasever - $basearch
failovermethod=priority
baseurl=http://download.fedoraproject.org/pub/fedora/linux/releases/$releasever
/Everything/$basearch/os/
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$releasever&
arch=$basearch
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$basearch

Our job is to copy and modify it so Yum and the GUI app manager can use the DVD. First you need to copy the block of code pertaining to [fedora] and paste the copy into your file – after [fedora] is fine.

  1. Change the line [fedora] to [fedora-dvd]
  2. change the name line to name=Fedora 10 x86_64 - DVD
  3. change the baseurl line to baseurl=file:///media/Fedora%2010%20x86_64%20DVD (the path to your DVD might be different – check it first)
  4. delete the mirrorlist line
  5. make sure the enabled line is enabled=1 (you can turn it off later through the “Software Sources” app)
  6. Save and exit

Use Yum or the Application manager to install. Rather than taxking your network and your patience you’ll see the DVD activity light busily blinking as you begin installing packages. One tip you might need to keep in mind is that refresh packages button on the package manager. There were a few packages I tried installing that were no longer available when I turned-off the net-based repo source. This is equivalent to yum clean [option]

Happy installing!

Hey there! Come check out all-new content at my new mistercameron.com!