Our DNA is written in Swift

"AppRanking for FREE" by Michael Dorn

NOTE: AppRanking has been deprecated in favor of Applyzer.

Michael Dorn (my collaborator on LuckyWheel) just couldn’t stand having to dig through iTunes to find how our game is doing in 62 iTunes countries. So he took it upon himself to create a nifty tool that allows you to conveniently look up rankings of any app. He wrote it in RealBASIC as an OSX desktop app in less than one day.

AppRanking Screenshot

Michael makes it available to all readers of Dr. Touch because it’s just soooo useful. And for free, that’s how nice he is!

AppRanking for FREE (No longer available, see above note)

It’s a ZIP file with an Mac APP inside. Again, like all free software this comes without any warranty. Use at your own risk.

Minimum/Maximum of Multiple Values

MadIvad asks:

Is there some sort of math function for the minimum of a set of values? I have searched the docs and not found one reference to math in iPhone OS2.2, and min only returns the like of ‘minimum’ for different control values. or for stating what the minimum of the integer or NSUInt class etc…

Does a function/class/anything exist that would simply return the lowest value of 2 or more values?

Boy, that was easy. There are compiler macros defined that work on any scalar datatype. MIN(a,b) and MAX(a,b). Note the case.

Read more

Cracker Tracker and Apple Stalker

I would like to draw your attention to two ideas that might work if enough people organize and contribute. I know that your time is valuable and most of you won’t have extra time to spend helping with a “good iPhone cause”, but hear me out. If we organize, contribute automatically we can all benefit enormously.

Read more

Variable Number of Decimal Places

Trapper asks:

I have one integer holding a variable number of decimal places that another variable needs to be rounded to when I stringWithFormat it. What is the correct way to do this?

Trapper is not content with just specifying %.2f in a stringWithFormat, but he wants the number of decimal places to be dependent on a second variable.

Here is the shortest method I came up with.

int decimals = 3;
double d = 3.1415;
NSString *format = [NSString stringWithFormat:@"%%%0.1ff", decimals/10.0];
NSString *formattedString = [NSString stringWithFormat:format, d]; // e.g. %0.3f 

I got confused at first because the NSLog would always output a strange value when wanted to output the formatting string. Then I remembered that the first parameter of NSLog itself is also interpreting formatting information. NSLog combines stringWithFormat into the output.

That’s good to know in case you want to add an NSLog statement for debugging floating point variables.

double d = 3.1415;
NSLog("%0.2f", d);  // formatting directly here

Don't Quit Your Day Job

Rob asks:

I have decided to start writing apps as a full time job. Assuming I can master this, and assuming I can get 1 app per month accepted in the App Store, can anyone give me some guidance on how much income I am likely to make.

Here are some numbers from my data that might help you:

  • A general purpose tool app like GeoCorder might sell between 1 and 5 copies a day.
  • Something interesting or unusual like iFR Cockpit can expect to sell around 5-10 copies a day.
  • A niche market tool like iWoman might to do well at 10-20 copies a day.
  • A game like LuckyWheel would sell around 20 copies a day IF you also have a LITE Version that has about 900-1000 downloads a day. Without a LITE version it could only be 5-10 copies a day.;-)

So assuming you concentrate on niche apps and games and calculating from $25 a day per such app you might make around $2000 a month if you manage to land 3 of those in the store. NOT taken into account additional cost like taxes or hardware. And not considering that Apple has the painful final word. Does that sound easy enough for you to immediately quit your day job?

For me it didn’t and it took me 8 months to get where I am today. It’s ok to see it as a lucrative hobby or even second income, but to stake your existance solely iPhone development you have to be extremely disciplined. Or even better: to know how to build teams of bright minds who can bring skills to the table that your don’t possess yourself.

Anything goes … into NSArray

When switching to or beginning with Objective C you might be tempted to try to use the old c-style arrays, but that’s better left to the hard core C-enthusiasts. For programming Cocoa Touch we always use the NSArray class because of the additional intelligence it provides for us, not to mention integration with memory management.

The first thing I ever added into NSArray was string objects. And so will probably everybody who starts with Objective C.

NSString *someText = @"Static Text";  // static allocation
NSString *someMoreText = [[NSString alloc] initWithString:@"More Static Text"]; // manually allocated
NSArray *myArray = [NSArray arrayWithObjects:someText, someMoreText, nil];  // note the nil
[someMoreText release];  // don't forget to release
NSString *retrievedText = [myArray objectAtIndex:1]; // first index = 0

How about numbers? Generally you can only add instances of objects into NSArray. But luckily Apple has created the NSNumber class which provides a container object for any kind of number, i.e. int, float or even BOOL.

int i=123;
float f=5.0;
NSNumber *num_i = [NSNumber numberWithInt:i];
NSNumber *num_f = [NSNumber numberWithFloat:f];
NSNumber *num_b = [NSNumber numberWithBool:YES];
NSArray *myArray = [NSArray arrayWithObjects:num_i, num_f, num_b, nil];

With the methods above you are able to add strings and numbers into arrays. There is yet another wrapper class that allows to put even more complex data types and structs into arrays: NSValue. Most usefully are the UIKit additions to NSValue which give you the possibility of packaging CGRect, CGPoint, CGAffineTransform or CGSize structs into objects. And those are just as easy to put into an array.

CGRect aRect = CGRectMake(0, 0, 100.0, 100.0);
CGSize aSize = CGSizeMake(10.0, 20.0);
NSValue *val_rect = [NSValue valueWithCGRect:aRect];
NSValue *val_size = [NSValue valueWithCGSize:aSize];
NSArray *myArray = [NSArray arrayWithObjects:val_rect, val_size, nil];

Soon you will find it odd that NSArray does not have any method to add and remove objects. The reason for this is that most standard objects are non-changable (aka “immutable”) as such. To gain such modification features you have to use the mutable cousin NSMutableArray. This gives you methods like addObject or removeObject.

NSMutableArray *myArray = [[NSMutableArray alloc] init];
[myArray addObject:@"first string"];
[myArray addObject:@"second string"];
[myArray addObject:@"third string"];
[myArray removeObjectAtIndex:1];
NSLog([myArray description]);  // a quick way to show contents
[myArray release];

NSArrays are the meat and bones of most Objective-C apps. Anybody trying to master this language has no way around them.

LuckyWheel 1.0.3

Since we released LuckyWheel 1.0.2 together with a Lite Version we have around 1000 new downloads every day. Of course we are listening to all the user feedback und therefore I am hastily pushing out a new update. This is mostly aimed at the many Italian users, but one change will also benefit Spanish and French players.

  • Italian UI and Instructions added
  • accented letters are now counted as guessed correctly if you guess the non-accented letter. i.e. E = È
  • completely replaced Italian proverbs with cleaned up set
  • prettier icon

Depending on how long Apple takes to check it out I guess you will see the update appear in about one week.

Apple Rejects Incredibly Useful iTunes Report App

ASiST First screenshotMostly out of personal necessity I had created MyAppSales to download and chart the sales reports available on iTunes Connect, the website where Apple makes daily reports available for only 7 days. A dozen BETA testers helped me improve it and iron out some kinks and finally it was ready to be submitted for sale on the app store.

Some people suggested that Apple might not want any app to interface with their website, but someone found an all called Sales Report on the app store for $14.99 which does precisely that. I assumed that Apple had to be fair and allow all apps that do the same thing. So I submitted it.

There was an occasional back and forth where every time I got an additional line of the full answer, but I kept arguing for fairness. After many weeks of keeping my app MyAppSales under review they finally came back with a rejection reason that I cannot counter:

Thank you for submitting your application to the App Store. Unfortunately, your application My App Sales cannot be added to the App Store because it violates section 3.3.7 of the iPhone SDK Agreement:

“Applications may not use any robot, spider, site search or other retrieval application or device to scrape, retrieve or index services provided by Apple or its licensors, or to collect information about users for any unauthorized purpose. ”

There is no public API allowing information from iTunes Connect to be used in the manner demonstrated by your application. 

Now I am baffled. I and a dozen other people keep using MyAppSales and we are quite happy with it. But Apple seemingly does not feel a moral obligation to appliy those pesky SDK Laws equally to all developers.

Requests for comment about why the other app is still available on the app store have not been answered so far. I sent an e-mail to “Maringo Holdings, LLC” to congratulate them for having successfully outsmarted Apple.

Currently I have no time or strength to rip out the heart and usefulness from my app. Therefore for now I am offering the source code for purchase. You can compile the app yourself and use it on all your iPhones as you please. I think $15 is a fair price. Send it to me via PayPal ( and I will send you the source project. I will also keep providing free updates to source license holders.

Maybe in the future I will find a workaround, either via an FTP server in between Apple and the App or maybe interface with one of those numerous services that are popping up proposing to manage your reports online.

SSD Impressions: I’m Supercharged!

Lately we saw prices for SSDs beginning to drop because of increased competition between manufacturers of RAM chip based products. Once a colleague of mine showed off his mid-2008 MacBook running on an SSD my envy-bone was tickled.

Doing due diligence I found a couple of sites advertising lower prices, but only Amzon actually had the OCZ APEX 120GB in stock. So I headed over to to purchase one. Actually I went to the German site, where I shelled out 370 Euros, users in the US have to pay even less. So the OCZ APEX currently blows the competition out of the water in terms of price/performance.

Before installing I used XBench to gather a few stats on the original HDD in my mid-2008 MacBook Pro. Also I timed a couple of other usual tasks to have a basis for comparison. What good is having an impressive machine if nobody knows about how great it is? 😉

At first I was enthusiastic to install it myself but without the proper tools I was not able to remove the final bracket holding down the drive. Over night my charger died and I feared the worst because I was no longer able to boot my MBP with empty battery. So I took it all to an authorized Apple Support Center in Vienna, asking for a repair and while they where at it, to also install the SSD. With the Guide at iFixIt anybody can make the upgrade themselves, provided they get the necessary tools in advance.

I had to pay a full hour work plus 50% extra for express service, the charger exchanged for a new one for free. But at least I got my MBP back the same day, SSD installed and a basic Leopard 10.5.6 on it. It took me a while to copy back all files and settings from the SuperDuper image I had created the day before, but the next day I was ready to evaluate the performance difference.

The OCZ APEX model has an internal RAID 0 with two chips working as one which effectively doubles the throughput which goes over the SATA 2 interface. This is compatible with the SATA 1 in my MBP, which rates at 1.5 Gigabits, or about 150 theoretical Megabytes per second. OCZ claims a read rate of up to 260 MB/s and up to 160 MB/s for writing for the APEX series. This is why I chose it because I wanted to max out both the reading and writing throughput possible over SATA 1 at the lowest possible price for 120 GB.

So much for marketing, here come the real life results:


All of the numbers speak rather clearly. On average it is fair to say that the SSD is four times as fast. But even more impressive than benchmark numbers is how much faster those many standard tasks become. This is what you actually notice.


Most of the time of the booting process is unrelated to the performance of the harddisk but is spent checking the RAM, loading the EFI etc. Once the turning wheel appears it is only a few seconds before the desktop is visible and fully active. Shutdown is most impressive, but who really shuts down his Mac anyway? MacBooks are the only laptops I know where you can close the lid to standby and open it to immediately continue working.

Opening apps generally is three times as fast, building times with XCode are effectively halfed.

The other side effects of coding on an SSD-based MacBook Pro are almost as obvious:

  • Shock Resistance. If you smash your MacBook to pieces (up to 1500G) the data on the SSD will still be intact. This goes hand-in-hand with the next point.
  • Data Safety. You eliminate a single point of failure from your development system as head crashes are still the worst total failure possible. And they do happen. How valuable is the code you write while on the road without being able to back it up?
  • Power Consumption. Reduced. Maybe. Slightly. A few minutes.
  • Noise. There is no clicking to hear if you put your ear on your top case. You now have to rely on the fans to know that your MBP is still alive and has not become an undead vampire.
  • Less time spent waiting. If you consider all those reduced waiting times for the multitude of small tasks involved in created an app, all those Seconds will add up to days until the end of your life.
  • Bling Bling. If you happen to mention that you have changed to SSD most people will either think you are rich or the Uber-Geek.

If only I could get my hands bionically enhanced then this would also tripple the amount of code I can write while sitting on the train. But until I do I have to be content with the advantages outlined above.

Was that you that I just overtook in cyberspace? 😉

Exercise: Compile Wolfenstein 3D for iPhone

If you are around my age then the first 3D Shooter you have played might have been Wolfenstein 3D. Still unforgotten and causing a smile are the words “Ahhh, mein Leben!” shouted by German soldiers expiring.

John Carmack, coding god and founder of ID software has spent some time on creating an iPhone conversion and graciously provides the source code for it on ID’s FTP server.

If you download it and dig through the ZIP file you will find a letter from John and a read me explaining that the iPhone code is found in wolf3d/newCode/iphone. Browse there and open the wolf3d.xproj file to open the project in XCode.

If you just hit Build&Go you get two error messages where two symbols cannot be resolved by the linker. There is a workaround on with which you can compile and run Wolf3D on the iPhone Simulator.

If you switch to iPhone as target platform you get the usual message that the currently set certificate cannot be found for code signing.


Code Signing Identity ‘iPhone Developer: Cass Everitt’ does not match any code-signing certificate in your keychain.


This is easy to fix. Simply replace the mentioned signing identity with your own development identity. This is in the info of target wolf3d.

After this you are good to go. The app installs on your development iPhone and runs very well. At first I thought that sound was missing, but that was because my ringer switch was off. 😉

Wolfenstein 3D on iPhone

Next I’ll insert my own “Mein iPhone!” sound effect for a more modern touch. 😉