Creating Demo Videos of iPhone Apps

January 12th, 2010

Mobile Orchard, the #1 iPhone Developer News site, published a couple articles I wrote detailing how to create demo videos of iPhone apps:

Enjoy!

cocoasudo: A graphical Cocoa based alternative to sudo

October 26th, 2009

Sudo is “a program for some Unix and Unix-like computer operating systems that allows users to run programs with the security privileges of another user (normally the superuser, a.k.a. root).” (Wikipedia reference). It works great for command line applications – especially for running them from a terminal prompt, or as part of a shell utility.

For Mac OS X Cocoa-based apps, there is analagous ability to sudo provided via the Authorization Services API. Use of the API allows you to prompt the user for their username and password requesting the ability to escalate privileges.

System Preferences app's use of Authorization Services API

System Preferences app's use of Authorization Services API

The Authorization Services API is a bit complicated. All the more so if you’re not writing a Cocoa app in Objective C. For example, maybe you’re using a scripting language, or you’re writing your GUI in Java / Swing for cross-platform use.

For that case, I’ve written a small utility that I’ve dubbed cocoasudo. Use cocoasudo in much the same way you’d use sudo. However, instead of users being prompted for their password in a Terminal window, they’ll get a dialog prompt via the Authorization Services API.

Usage:

cocoasudo [--icon=/path/to/icon.icns] ["--prompt=This prompt will be displayed to users."] command-to-launch [command-arguments...]

Both the –icon and –prompt parameters are optional and may be omitted.

Download the source on Github, or via your git client:

git clone git://github.com/performantdesign/cocoasudo.git

Or, if you don’t have Xcode, or don’t want to compile from source, you can download the cocoasudo binary directly here.

cocoasudo is Apache-licensed, so you can mostly use it as you see fit.

Tell iPhone Devs – Pick Up The Phone!

September 16th, 2009

At 8:45 Monday night, I received a call from an unrecognized number with a 408 area code. As a general habit I do not answer unrecognized calls in the evening. The iPhone said the number originated from Palo Alto, but I didn’t think much of it. 30 seconds later I received another call from the same number. Still didn’t answer.

Soon, my iPhone indicated I had a message: “Aaron, hi my name is ____, I’m calling from Apple. Would you call me back as soon as you get this message, please? It’s regarding a very timely marketing opportunity. 408-xxx-xxxx. Thanks very much. Speak with you soon. Bye-bye.”

At this point, my jaw dropped. This is exactly the kind of call I had been hoping for, but realistically I never expected to get. Standing out in the App Store is difficult, and this could be a big opportunity for the iGarageSale app.

It was late in the evening and I was at home hanging out with my son. I quickly scrambled to get him a toy to occupy him for a couple minutes, and then I returned the call. The gentleman at Apple indicated that they were interested in featuring iGarageSale in iTunes and that they really like the app. However, they wanted me to change a bit of the description first.

Purchasers of iGarageSale receive a free MP3 download of “Holding On” by the independent artist, Mr. J. Medeiros. This is the song featured as background music in the demo video for iGarageSale. Apple was fine with purchasers getting a free copy of the song as this is something that had been legally agreed to with the artist, but they wanted me to remove that fact from the description of the app in iTunes. They wanted people to buy the app for its own merits, not in the hopes of a free bundled MP3. I assume this is also to avoid potential confusion and complaints directly to Apple later, which is understandable. Since they didn’t require me to take away the freebie – just the promotion of it in the iTunes description, I said I’d make the change immediately.

The Apple representative asked how sales of the app were going and I said “OK, but not where I’d like them to be. Certainly having the app featured in iTunes will help!” He responded saying “Well, we’re not promising anything.” Then he chuckled and said, “But you might want to check the App Store tomorrow.”

Three hours later (around midnight), I saw this on the front page of the App Store section in iTunes:

iGarageSale - New And Noteworthy in iTunes

Naturally, I was pretty stoked to see this.

Yesterday was the first full day the app was featured in the New and Noteworthy section of iTunes. So, what kind of difference does it make to be featured?

iGarageSale Revenue Graph

Other peaks on the graph cover things like the first weekend of the release, an ad campaign the following week, pricing promotions, and the introduction of a Lite app. However, all of those events pale in comparison to being featured in the App Store.

So, in conclusion – if you’ve released an iPhone app and you get a call from a 408 number, I suggest you answer!

s3-bash – No newline the secret key file

September 14th, 2009

If you use the s3-bash utilities with Amazon’s S3 service, you’ll find that one of the parameters asks for a file that contains the secret key. There’s important thing to note about this file – it must contain just the secret key without a newline. To check this, listing the file with ls -l should show that the file is 40 bytes. If it’s 41, you’ve got a newline and it won’t work. If you don’t have a text editor handy that will do this for you, you can use the following command to output your secret key to a file without the newline:

echo SECRET_KEY_HERE|tr -d '\n' > secret-key-file

Facebook iPhone Session Proxy in PHP (FBSession getSessionProxy)

September 3rd, 2009

If your iPhone app incorporates the Facebook Connect for iPhone library, one of the first things you will do is instantiate an FBSession object. Developers are given two choices for this according to the wiki:

session = [FBSession sessionForApplication:myApiKey secret:myAppSecret delegate:self];

or:

session = [FBSession sessionForApplication:myApiKey getSessionProxy:myURL delegate:self];

The first option is quick to implement, and an OK option for initial testing. However, it is inherently insecure as it requires you to release your Facebook application’s secret key embedded in your code.

Unfortunately, implementing the second option isn’t straightforward. Read the rest of this entry »

scrollIntoView, but only if out of view

August 26th, 2009

On browsers such as Firefox, the scrollIntoView function silently returns without action if the element in question is already on the screen. However, in IE6, and perhaps other browsers, it causes the screen to scroll even if it is already in view. To workaround this, and only call the scrollIntoView function if the element in question is out of view, I wrote the following helper method — scrollIntoViewIfOutOfView.

Read the rest of this entry »

find | xargs grep: hack of the day

September 5th, 2007

Even with today’s modern IDE’s and plethora of search tools (Spotlight, etc.), I still find myself occasionally dropping to a bash shell to look for something in an unknown file. In the past, I was a bit frustrated that my combination of find | xargs grep would bomb out on any files or directories that included a space. Today it dawned on me that there’s a simple workaround for this… Prefix and postfix each file with a quote via sed. The following example recipe will find the text textIAmSearchingFor in any .java file in the current tree.

Read the rest of this entry »

Yahoo! Pipes, PHP, and web services

September 1st, 2007

I’ve finally taken the time to play around with Yahoo Pipes. I’ll probably do a few posts over the next couple of days on my findings, but I’ll get started with the basics on how to write a json web service in PHP that can be called from Pipes. The capability to call a web service from Pipes is a recently added addition by Yahoo that could prove to be very powerful.

There’s a good post and recipe for getting started over at echoditto labs. Unfortunately, my web host had two things that made this recipe a non-starter. First, they don’t allow compiling C++ extensions for PHP, as is required by the JSON PECL package. Second, they have PHP’s annoying little magic_quotes_gpc setting turned on.

Here’s a little recipe that may help you get started. You’ll need to first download the Services_JSON library — a proposed addition to PEAR that encodes and decodes JSON. The recipe below assumes that you use items as the input for the “Path to item list” prompt in Pipes. The recipe is simple and straightforward. It is the moral equivalent of Yahoo’s Java example — it simply appends ” (This text was added by the external Web Service)” to the title of each item in the feed. It provides one additional bit of functionality that may help you get started. It logs the decoded input value to pipes-log.txt. This will help give you an idea of what your input is.

Read the rest of this entry »

Pipe your current results in less to a file

August 29th, 2007

If you’re ever faced with having piped a long-running process into less, and then you suddenly realize you want to save those results, and don’t want to run that long-running process again, here’s a quick trick to pipe your current results out to a file:

1G (go to the first line)
|$cat – > file.txt (pipe everything to the end of the file to file.txt)

PS – Please comment if you’ve found an easier means to this end.

Simple Method for Tuning SQL Server

January 26th, 2007

I have written the following script and have found it to be a rather effective, minimally invasive, and low-tech way to track down troublesome SQL statements when tuning my apps for SQL Server. I’ll usually set it up as a SQL Server Agent job to run once per minute. It logs all currently running SQL statements to the SQLLog table, for analysis at a later date. (Note that the job must be run as the sa user, or another user with sysadmin privileges in order for the fn_get_sql function to work.) The thing I like about this technique is that it seems to get a good cross-section of both long-running statements, and statements that may be short in duration, but are run often. I’ll then do a count on statements to see where to focus my tuning efforts. Enjoy!

Read the rest of this entry »