Talk Funnel

Ramin Firoozye’s Public Whisperings

Archive for 2008

Tilt-shift video

with one comment

Tilt shift photography is a technique where a photograph’s focus appears blurred and only the center of the subject is in focus (there’s more to it, but that’s the gist of it). You can simulate it in Photoshop but it’s probably easier (albeit more expensive) to use special tilt-shift lenses. The effect is pretty cool, as if you’re photographing a miniature set. Some background on the technique here and here and some beautiful examples here.

The effect is used to stunning effect in this time-lapse music video made entirely with a tilt-shift lens:


Metal Heart from Keith Loutit on Vimeo.

Be interesting to see what would result if you put together the amazing Canon EOS 5D Mark II HD and a decent TS lens…

Written by ramin

December 13th, 2008 at 1:39 pm

Posted in Photography

Tagged with

Easy UIView debugging on the iPhone

with 5 comments

The user interface of the iPhone is based on a series of nested UIView objects, arranged in a view-subview/parent-child relationship. When building a complex application with a lot of views, sometimes it’s handy to be able to see exactly what that relationship is.

But if you try to print out the value of a UIView in the debugger (or through an NSLog function) you’ll be sorely disappointed. In this example we have a variable called front that is derived from a UIView. Setting a breakpoint in the XCode debugger, I type in a po (print object) command to show what that variable contains:

(gdb) po _front
<BCCardSideView: 0x106b020>

What you see is that the variable is of type BCCardSideView and its hex address. Not very helpful.

One solution is to take advantage of the Objective-C dynamic runtime and override UIView’s default describe method. This is the method that is called every time you try to display the value of an object. Here we have just such an override that recursively walks the view tree and dumps out the values. The code is contained in a file called UIViewExtras.m. All you have to do to enable it is include the file in your XCode project. There are no explicit methods to call.

Here’s the same output after UIViewExtras.m is included in the project (the indentation is a little messed up because of the column width of this blog. In the debug window, it should look fine):

(gdb) po _front
+ BCCardSideView retain:3 - tag:0 - bgcolor:(r:0 g:0 b:0 a:1.00)
bounds: x:0 y:0 w:130 h:80 - frame: x:5 y:5 w:130 h:80 - center: x:70, y:45
++ BCCardBackgroundView retain:4 - tag:0 - bgcolor:(r:255 g:255 b:0 a:1.00)
bounds: x:0 y:0 w:130 h:80 - frame: x:5 y:5 w:130 h:80 - center: x:70, y:45
++ BCCardTextView retain:4 - tag:0 - bgcolor:(r:0 g:255 b:255 a:1.00)
bounds: x:0 y:0 w:100 h:20 - frame: x:0 y:0 w:100 h:20 - center: x:50, y:10
text (len:4 - color:r:0 g:255 b:0 a:0.00): 'name'
++ BCCardTextView retain:4 - tag:0 - bgcolor:(r:255 g:255 b:0 a:0.00)
bounds: x:0 y:0 w:100 h:20 - frame: x:0 y:20 w:100 h:20 - center: x:50, y:30
text (len:5 - color:r:0 g:255 b:0 a:0.00): 'title'
++ BCCardTextView retain:4 - tag:0 - bgcolor:(r:0 g:0 b:255 a:1.00)
bounds: x:0 y:0 w:100 h:20 - frame: x:0 y:40 w:100 h:20 - center: x:50, y:50
text (len:5 - color:r:0 g:255 b:0 a:0.00): 'email'
++ BCCardTextView retain:4 - tag:0 - bgcolor:(r:255 g:0 b:0 a:1.00)
bounds: x:0 y:0 w:60 h:20 - frame: x:0 y:60 w:60 h:20 - center: x:30, y:70
text (len:7 - color:r:0 g:255 b:0 a:0.00): 'phone.1'

For each view object you see:

  • The retain count.
  • The tag value (if specified).
  • The background color value in RGBA. RGB values are scaled up to 0..255 and alpha is shown as a floating point value between 0 and 1.
  • View bounds rectangle (x, y, width, height)
  • View frame rectangle (x, y, width, height)
  • View center (x, y)

If view is a UILabel or UITextField, you also get:

  • - Length of text
  • - RGB value for text itself (vs. the background)
  • - Actual value of the ‘text’ inside the field.

Subviews are indented by multiple “+” (plus) signs. So the top-level has one ‘+’ all its subviews have two ‘+’ signs, *their* subviews will each have three ‘+’ signs etc.

I personally find this handy in debugging views — especially those created dynamically. I hope you do too.

[ Download: UIViewExtras.zip ] (Update: Link updated.)

Update 2 [06-Oct-09] : Modified method of obtaining class name so it should work with newer SDK releases.

Written by ramin

December 11th, 2008 at 2:49 am

Posted in Tech

Tagged with , ,

Thoughts on Professional iPhone Development

with one comment

Idea vs. Execution

Raven Zachary in a post on the O’Reilly Inside iPhone Blog raises the old idea vs. execution argument. *Sigh*. This is the same debate I’ve been hearing (and having) for the past twenty years and it keeps popping back up again.

Folks, it’s not zero-sum / either-or. It’s both. One hand holding the other. Yin and yang. It’s like saying who was more important in your creation: your mother or your father? (OK, some might say it was the Rum and Coke, but remember that’s just the catalyst.)

A lot of people bandy about the phrase “Ideas are a multiplier of execution.” As near as (Google) can tell, this phrase was popularized in a short post by Derek Sivers. What most people ignore is the conclusion he posits:

To make a business, you need to multiply the two.

In other words: I * X = success

If either I (idea) or X (execution) values are low (or zero) the outcome suffers–or stays at zero. Without a good idea, the best developers will sit around and play games or post rubbish on Twitter. Without a good implementation the best ideas will sit around till the cows come home. And the converse is true as well (bad idea/bad execution).

Architects can draw as many designs as they want, but without the builders nothing will get built. The builders can build the most fabulous walls but they won’t quite connect because they don’t have good plans.

Shall I go on? (NNNNoooo!)

So the next time you discount somebody’s idea by assigning it a value of $0, you may want to pause and give it another listen. Naturally, there are lot more ideas than implementations, but that doesn’t mean ideas are worth $0. It just means you need a knack for sifting the good from the bad. And let’s not forget good and bad are subjective valuations. If it wasn’t so, all movies and games would be instant hits.

OK, ’nuff said. I’m sure this isn’t the last time I’ll be hearing this debate again.

Product vs. Project

On a different topic, if you go by Raven’s numbers your typical developer making $125/hr working full-time will gross ~$250K a year (most developers I know work only part-time, however). If they write an app, put it on the app-store and it sells, say, 30,000 copies for the year (a conservative estimate) they would need to price it at around $10.99 in order to match the consulting rate. Write a hit (say, 100,000+/yr) and at that price, you’d be waaay ahead of the hourly rate.

The dilemma most professional iPhone developers will face is whether to take on a consulting project or spend the time working on their own product. I can tell you from personal experience, it’s pretty damn hard doing both. In a perfect world, you could do one for a while then switch to another. But it rarely works that way. While doing consulting, you’ll have to battle the constant nagging feeling that you’re actually losing money by not having your product out there and the opportunity may well slip away when someone else beats you to the market. On the other hand, while working on your product and not generating income, it’s hard to say no to someone offering you cash.

It’s a tough choice (and you should drop to your knees and kiss the ground if you’re lucky enough to be facing such a dilemma.)

Pricing

The other thing to keep in mind is that if you’re planning on writing an app for yourself and pricing it low (say, $0.99) then you’re looking at a heckuvalot of copies to make it worth not going the consulting route. iPhone developers wanting to do product development for themselves and make a good living at it might want to take Andy Finnell’s sage advice and price their apps at a more reasonable rate–something that would at least cover their costs and allow them to turn down subsequent time-intensive consulting gigs.

My personal feeling is no competent developer should be putting out $0.99 apps. They’d only be shortchanging themselves. The iPhone store is in its early stages. It’s too early to have all the shelves be stocked with apps retailers put in the discount bargain bins.

Written by ramin

November 22nd, 2008 at 1:25 am

Posted in iphone

Tagged with

Slowing down Time Machine

with one comment

Time Machine is great, especially if hooked up to a network storage device like Drobo so you can just have it run in the background. In my case the Drobo is connected to a Mac Mini acting as a network file server (yes, I know it’s not officially supported, but it works fine under Leopard).

However, lately the backups have been taking a lot of system and network resources, rendering the machine (in this case my development laptop) practically unusable while they run. But since Time Machine runs in the background, it’s OK to lower the backup daemon’s priority and let it run a little slower.

On Mac OS X Leopard, this is the command that does the trick. From the terminal:

sudo renice +5 -p `ps -axc | grep backupd | awk '{ print \$1 }'`

Here’s what’s going on:

  • sudo – This runs the command as the root. You will need to enter the administrator password.
  • renice – This is the standard Unix command for changing the priority of a running application.
  • +5: Process priorities under BSD Unix-based systems typicall run from -20 to +20, with +20 being lowest (i.e. running slowest) to -20 being maximum (yes, I know it’s unintuitively backward, but there’s an old historical reason for it). What we’re doing is bumping Time Machine daemon’s nice priority up by 5 (or any number you want) to let it run slower.
  • -p pid – This is the process id of the process you want to adjust. Since this changes every time Time Machine runs, we have to have a way to find it dynamically at runtime — which is where the rest of the line enclosed in ` back-quotes come in. On most Unix shells, items enclosed in back-quotes get executed and the result returned back to the command line. So we’re going to look up the process ID of the current Time Machine server process and return it here.
  • ps -axc – The ps command returns a long list of all running processes on the system. We need to filter out the one we want, which we do by piping the output into a grep filter next…
  • grep backupd – We’re taking all the output from the ps command and only keeping those lines that contain the string backupd — which happens to be the name of the Time Machine server. So we end up with a single line of ps output that looks something like this:

    19041 ?? 1:07.48 backupd

    But what we need is the process ID to pass back up to the renice command. In this case, it’s the first number on the line. We need a way to extract only that, which is where awk — the amazing text processing Swiss-Army knife — comes in…

  • awk “{print \$1 }” – By default, awk splits its input into chunks based on whitespace. We’re simply asking that the first item be returned. Any time you do this, you should apologize to awk for so massively under-utilizing what it can do. It’s like driving your Formula-1 car down to the grocery store to buy milk. In this case all we’re doing is asking it to split up some text and return one item to us, something that awk can do practically in its sleep.

When you run this, the sudo part of the command will ask you for your admin password, then proceed to do its thing. Put it all together and you’ve got yourself a simple way to slow down Time Machine so it’s not such a CPU hog.

If you’re enterprising, you can put the whole thing into a shell function and run it over and over. The following code goes inside your .bash_profile file.


function tmslow {
    echo "Reducing Time Machine priority..."
    sudo renice +5 -p `ps -axc | grep backupd | awk '{ print \$1 }'`
}

Start a new terminal session (to make sure the shell function is loaded) then invoke tmslow and enter your admin password. It prints out a little message reminding you what it’s about to do.

Remember, the renice command doesn’t stick, so every time you reboot or a new Time Machine session starts, the process goes back to normal priority. There are ways to automate the priority lowering scheme or even make it permanent, but I don’t recommend doing that. Sometimes, you may want backups to run full-speed. Unix makes it trivial to do what you want by stringing together some built-in commands.

Written by ramin

November 8th, 2008 at 9:35 pm

Posted in Tech

Tagged with , ,

On 50

without comments

This came through the mail recently. I’m not quite there yet age-wise, but still found it funny:

Advantages of approaching (or passing) your 50th birthday:

  • Kidnappers are not very interested in you.
  • In a hostage situation you are likely to be released first.
  • No one expects you to run–anywhere.
  • People call at 9 pm and ask, did I wake you?
  • People no longer view you as a hypochondriac.
  • There is nothing left to learn the hard way.
  • Things you buy now won’t wear out.
  • You can eat dinner at 4 pm.
  • You can live without sex but not your glasses.
  • You get into heated arguments about pension plans.
  • You no longer think of speed limits as a challenge.
  • You quit trying to hold your stomach in no matter who walks into the room.
  • You sing along with elevator music.
  • Your eyes won’t get much worse.
  • Your investment in health insurance is finally beginning to pay off.
  • Your joints are more accurate meteorologists than the national weather service.
  • Your secrets are safe with your friends because they can’t remember them either.
  • Your supply of brain cells is finally down to manageable size.
  • You can’t remember who sent you this list.

Written by ramin

October 30th, 2008 at 2:09 pm

Posted in Fun

Tagged with

Notes from the iPhone Tech Talk

with one comment

I spent all yesterday at Apple’s first iPhone Tech Talk in San Francisco (technically, Paris was first because of time differences, but we won’t quibble). After seeing the schedule of events (and having attended WWDC) my expectations for getting new technical information were pretty low.

Boy, was I wrong.

The talk itself was under NDA so I won’t go into details. But I’ll point at a couple of items in current examples and documentation that everyone should be aware of:

  • If your app is using audio in any way, you’ll want to make sure you’ve read and understood the “Audio Sessions: Cooperating with Core Audio” section of the “Core Audio Overview” document (it’s part of your help document set in the SDK).

    Of special importance is making sure you declare the proper AudioSessionCategory for your app. Not doing it means that if your app uses sound (input or output) and gets interrupted — by an incoming phone call, or even by the user plugging and unplugging headphones — your app’s sound may not continue playing properly. There’s some example code in the SpeakHere example to help point the way.

    Here, by the way is what the documentation says:

    Ignoring Audio Session Services will not prevent your application from running, but your app may not behave the way you want it to. Never ship an iPhone or iPod touch application that uses audio without using this interface.

    You’ve been warned.

  • If you’re using the accelerometer, you’ve probably seen the low-pass filter code in the docs and examples. The point of the filter is to smooth the effect of motion ‘jitter.’

    The thing is, the basic low-pass filter formula is — to put it mildly — non-functional (aka brain-dead). Again, I can’t talk about the specifics, but the presenter had graphs that showed how bad that formula behaves.

    Actual color graphs, I tell you!!!

    If you manage to get your hands on a sample iPhone Apple application called Touch Fighter — you’ll want to use the smoothing function there (the app was handed out in WWDC and isn’t part of the standard SDK example set).

    If you can’t find it, I suggest looking around for source code that handles the Wii remote (they have to deal with similar issues). At some point, I might post a more detailed technical article on this.

  • Gesture management is still something that Apple leaves to individual developers, instead of including it in the SDK. I have a ‘swipe’ detection library (but it’s only for one-finger swipes, not multi-touch). If there’s demand for it, I’ll post it up.

    But really, this should be something supported in the OS.

Most of the TechTalks are full now. If you happen to have gotten accepted, don’t skip them. If not, get on the waiting list. It’s worth it. The sessions on game development and performance tuning are massive info-dumps. Might want to take a lot of notes.

P.S. That mod-squad picture on the web site (excerpted above) features actual Apple evangelism group members strutting their stuff :-)

Written by ramin

October 23rd, 2008 at 6:34 pm

Posted in iphone

Tagged with ,

Re-launch

without comments

I totally blame my absence from this space on Twitter, for sucking away what little time and energy I have to write things. However, with the removal of the iPhone NDA, I’m going to re-focus on what I’ve been spending most of my working time these days: iPhone app development.

That is not to say that I’ll stop posting other meanderings. Just that I need a place (other than mailing lists) to post and where better than, you know, my own damn blog.

Written by ramin

October 7th, 2008 at 10:40 am

Posted in admin

Tagged with , ,

Resetting styles

without comments

Sorry if the blog’s style keeps switching around. Problem seems to be with the DB and hosting site. It keeps resetting back to the default WordPress style even if I haven’t posted for a while.

Might just have to give up and leave it there. *sigh*

Written by ramin

September 11th, 2008 at 10:33 am

Posted in Tech

Tagged with ,

Setting the bar low

without comments

Ad for an institution of higher learning, currently circulating on national news outlet sites.

Written by ramin

August 22nd, 2008 at 12:02 pm

Posted in Tech

Tagged with , ,

The Most Determined Spammer in the World

without comments

This message popped into my email inbox today:

A few points worth mentioning:

  • The [SPAM] tag was not added to the subject header by any software on my end. As near as I can tell, it was either put there by the spammer’s own email server, or added manually.
  • The particular inbox to which the message was addressed is protected by a server-side whitelist service (SpamArrest). For the message to get through, somebody has to go to the trouble of explicitly confirming that they’re really a human and put themselves on the approved list. The sender did this.
  • The same message has been sent several times under different email addresses. Every time, I ban the address and a while later it makes its way again with a new sender address (which has to be manually confirmed with SpamArrest, again).
  • I feel bad for the ‘real’ Dr. Lulu Gwagwa of South Africa, who appears to be a most accomplished investment banker.

For some reason, the perpetrators of this message are really determined that this message get through and a lack of response (or continuous placement on the ban filter) doesn’t seem to deter them. That they consistently confirm their own address through SpamArrest tells me that they are not exactly high-volume ‘shotgun’ spam traffickers. Those people rarely provide a working reply address.

On the other hand, I have to admit that opening with an apology and the fact that they admit they got the email while doing a ‘random transaction’ on the Internet shows refreshing candor.

Sadly, I am forced to ban the sender once again, as much as I appreciate the effort.

Written by ramin

August 16th, 2008 at 10:21 am

Posted in Tech

Tagged with