Sunday, November 23, 2008

The new negative bias in iTune App ratings

About a month or two ago, Apple did a great thing with the iTunes App store review process. They required that reviews had to be written by people who actually downloaded the app. This eliminated a bunch of the "noise" reviews where it seemed you had people with free time on their hands and nothing better to do that post pointless reviews that said things like, "Is this app good? If so, click yes.", or those where someone wrote something like, "This app is so stupid I'm not even gonna try it!" and then gave it a 1 star review.

With the 2.2 iPhone OS update, Apple made another change to the review process. When you delete an app off your iPhone, an alert box pops up asking you to give a quick rating of the app - no text description, just a 1 to 5 star rating.

It's a clever idea, but it's one that is going to give a heavy bias toward low star ratings. If someone is deleting the app, odds are they didn't find the app useful, so odds are they are going to give it a low rating. Now the problem is, all the people who really like the app continue to keep it on their phone, so they'll never give it a positive rating unless they return to iTunes to specifically write a review.

I've already noticed this bias showing up with my apps. Over the past few days since the 2.2 OS update has been released, I noticed the average rating of my apps steadily going down while at the same time, all the reviews with a text description were pretty much all positive 4 and 5 star reviews. Since the apps I've been writing are targeting very specific audiences, someone who downloads the app just because they see it's a new free app will most likely not be interested in it, so will tend to delete the app and then give it a low rating when prompted.

Hopefully Apple will reconsider the idea of prompting for app reviews whenever the app is removed. Or maybe they could add the idea of prompting the user to write a review of an app they after they use it x number of times.

Friday, November 21, 2008

Radio Paradise

I have yet another "radio player" app in the iTunes App store. It's called Radio Paradise and, as the name implies, allows listening to music from the Internet radio station, I've been a listener for years, so I asked the owner of the station for permission to make an official iPhone app for the station.

I also used the app as an opportunity to test out a few additional features. The app will detect the type of connection you have (either cellular or WiFi) and will automatically use either a 64K or 128K stream. I originally had buttons in the app to allow the user to select the stream quality, however Apple rejected that idea because it would be possible to a user to select a 128K stream over cellular and in Apple's judgement that consumed too much bandwidth. I could have restrict the choice when on a cellular network, but for now I just simplified it and the app makes the decision for you.

The second feature this app uses is the inclusion of album artwork for the current track playing. Radio Paradise embeds in the audio stream the URL for the current artwork. So, it was simply a matter of having my app fetch the image as the song is playing.

The third feature is the implementation of a mini web browser. This will allow the user to visit the Radio Paradise web site while still listening to the music. Apple doesn't allow third party apps from running in the background, so normally if you were to launch Safari, the radio player is forced to exit. The mini browser also includes a button to allow the user to launch Safari if they really want to.

This app took by far the longest yet for gaining Apple's approval. It was almost a month! The biggest issue I kept running into was Apple claiming my app didn't throw up a message box informing the user when there was no network. I kept testing it and it always worked for me. After about 4 re-submission attempts, I finally discovered Apple was testing using the 2.0 iPhone OS and I was testing with 2.1. (It sure would have been helpful had Apple actually told me what OS they were testing with. I even asked, but never got an answer.) It turns out the "reachability" flags returned are slightly different between 2.0 and 2.1. Once I finally discovered that issue the app was quickly approved ("quickly" in Apple-speak means a few days).

Oh, and check out the size of this app - all those features and it's only 130K! Yes, K! I put my code on a diet! (Actually, it's because Apple's libraries, or frameworks, do much of the work and the frameworks are already installed on the phone.)

Monday, November 17, 2008

Building static libraries with the iPhone SDK

I have a client that wants to use my iPhone Radio Player code for their own radio station, however they want to be able to submit the app to iTunes under their own developer account. The gotcha is they are not purchasing my source code - they want to pay a smaller fee and just have me supply them with a binary image which they can then submit to Apple.

I do not have access to my client's Apple developer account, so I needed a way to supply the client with an Xcode project that includes a skeleton of source code along with a binary library that includes all the custom radio player functionality I have developed. This will allow the client to build the iPhone app and submit it via their account without giving the client access to my source code. Normally, one would probably create a custom framework to wrap up the custom radio player code, but in the case of the iPhone, this is not an option. Apple forbids the use of external frameworks or dynamic library linking in an iPhone app. Instead, I needed to create a static library containing my radio player code.

Fortunately, creating a static library for the iPhone turned out to be a fairly simple, but not at all well documented, process. If you already have an Xcode project, you can easily turn any portion of the source code into a static library. Here's how.

1) In your Xcode project, locate the "Targets" section under the "Groups & Files" sidebar. Right click on "Targets" and choose to add a new target:

Then, in the following dialog box that appears, choose a Cocoa Touch "Static Library" target:

Name the library whatever you'd like. In this example, I named the library "TestStaticLib."

2) Now, assign source code files to your static library. You can simply drag existing files from your project list. Note: don't add the .h files.

3) Then, remove those same source code files from your app target:

4) Add the new static library to your target app via the "General" settings for the target:

5) Edit your target app's linking settings to add "-ObjC" to the "Other Linker Flags". This is only required if your static library defines Objective-C classes that your app is going to reference:

6) Build your new static library for all the SDK targets (such as simulator, iPhone Device, etc.).

7) Build your app. It should now be referencing the static library rather than compiling from the original source code.

If you need to then distribute the app to a client, you can simply remove the source code for the static library and the client will still be able to build the app without having access to the original source code.

This technique might also be useful if you have some shared code you'll use in multiple applications, but don't want to recompile the shared code each time you make a new app that references it. Simply copy the shared library binary images to a specific location in your development environment and then have all your apps link with that code.