Ad

Our DNA is written in Swift
Jump

Adding Last Build Date & Time

If you need or want the date and/or time the last time your app was built then there are two handy macros you can use. Consider the following example:

char *date = __DATE__;  // e.g. 'Dec 15 2009'
char *time = __TIME__;  // e.g. '15:25:56'
 
NSLog(@"Build date: %s", date);
NSLog(@"Build time: %s", time);

I tested it with GCC 4.0, GCC 4.2 and even the new LLVM GCC 4.2. It worked fine with all three compilers.

Those are precompiler macros which work by getting the precompiler to replace them with the current date and time when the file in which they are located in gets built. Bear in mind that generally building is incremental and therefore these will only get updated if there really IS a new build happening. That’s a drawback if you forget it, but you can or should always do a build – clean before you build a release or distribution version to make certain all got updated.

Since those macros date back to C times they get replaced with C-style strings. That’s a pointer to a char array with a binary zero at the end to terminate the string. To convert them to obj-C NSStrings is simple by means of the %s formatter or by using one of the more complicated initializers of NSString.

char *date = __DATE__;
char *time = __TIME__;
 
NSString *myDate = [NSString stringWithCString:date encoding:NSASCIIStringEncoding];
NSString *myTime = [NSString stringWithFormat:@"%s", time];

Finally if you are really so much “pro” that the build time of your app matters, then you will probably also ask if there is a way to force building of certain files to forego the incremental building. Sure you can. All you need to do is to add an extra script to your target to set the last modified time of the file using these macros to the future.

touch -t 2012310000 "${PROJECT_DIR}/Classes/CalendarAppDelegate.m"

Touching Script

It’s not enough to simply set the modified time once because then the next modification sets it back to the current date. Thus the need for this simple unobtrusive script, in this example I am setting the modified time for CalendarAppDelegate.m to Dec 31st 2020 which is sufficiently far away so that this blog article will work for the next 11 years. 🙂

Waiting for Daily Reports

A developer based in the USA would probably never have to wait for the previous day’s sales report. But the iPhone app selling business being a global operation all EMEA and even more so APAC countries have to wait for a while until they can see how they are doing. That’s why I started to collect data on when a daily sales report usually becomes available so that I might be able to see a pattern or draw any interesting conclusions from that.

You might remember that I added anonymous availability reporting to MyAppSales 1.0.10. This way whenever a new report is encountered I am able to send out a push notification and automatically post it to the MyAppSales Twitter feed. The theory was that Apple would not make daily reports available at different times around the globe, but just have a single database that treats all developers the same. After a couple of days testing this hypothesis it was proven correct. In the beginning I was often myself the first person to see a report and thus trigger the notification. But very soon it started to happen that colleagues started to consistently beat me to the punch, be it either because they where more eager to get the report or just because the number of people with newer versions of MyAppSales exploded as I added more and more compelling features.

Now after 2 months Thomas Bonnin (thanks!) suggested to do an analysis, so I created a CSV file for the daily availability times for the past 2 months and Thomas kindly created these two charts from it. Bear in mind that the detection granularity grew over time, so at the beginning of this report the actual availability times might have been actually a bit lower.

Read more

Dr. Touch #007 – "Shaken not Stirred"

More and more video streaming apps arrive on the app store. More tablet rumors and a new iPhone coming next year.

Subscribe to the Podcast in iTunes

My script (aka “Show Notes”) after the fold below.

Read more

How to make a Pull-To-Reload TableView just like Tweetie 2

When I started on Twitter, I tried out a few Twitter clients both on Mac and iPhone until I quickly settled on Tweetie. When Loren Brichter made the bold move to sell Tweetie 2 as a seperate app I also purchased it because I am convinced this guy means quality and Tweetie 2 is on the first page of my springboard.

One thing that’s cool about Tweetie 2 is the fresh paradigm to refreshing the contents of a table view. Up until now we had been looking for space to mount a reload button on, sometimes having to resort to adding an extra tool bar for just one view so that you can have enough space. Now if you have a tableview that it sorted reverse chronologically, then you have a natural urge to make new items appear at the top by pulling down the table with extra force.

Loren recognized this need and innovated the Pull-To-Reload paradigm. If you want to refresh a tableview in Tweetie 2 then you simply pull down the table far enough for an additional cell to appear at the top with the instruction “Pull down to refresh”. If you do, then at a certain point the arrow rotates and the text changes to “Release to refresh”. All accompanied by two distinct wooshing sounds and a pop once the reloading action has ceased. The Intuitiveness of this paradigm is so compelling in fact that people who use Tweetie 2 start to try to refresh ALL tableviews like this.

Might be a good case to make this the standard way from now on because it feels more logical and natural than to tap on a small button with a circular arrow on it. A user of MyAppSales requested that I add this mechanism for reloading reviews of individual apps. At first I thought this to be advanced magic, probably using forbidden techniques. But after a bit of research and lots of hints coming from my Twitter friends (thanks Thomas and Fabian) I figured it out. This article explains how I did it.

Read more

MyAppSales 1.0.14 "Go Faster Strips"

There are a couple of users of MyAppSales who have been collecting daily reports since the first feeble beginnings. Turns out that if you have upwards of 300 reports in your apps.db then the previous method of loading everything at program start has a major drawback. There is a watchdog timer which kills any app that takes more than 20 seconds to start which caused a couple of users grief because that’s how long it took to load on iPhone 2G or 3G if you had that many reports.

This release is all about startup speed. On my own iPhone 3GS I managed to get from 12 seconds down to about 2. Also I was intrigued by the request to add a Tweetie-2-like Pull-To-Refresh mechanism, so that’s in there as well.

Changes:

  • Pull To RefreshADDED: Added Pull-to-Refresh on all review table views. Just like in Tweetie 2.
  • CHANGED: If a review text or rating changes then the review will now be updated and marked as changed.
  • FIXED: Country assignments for some report regions where incorrect causing financial reports to be incorrectly rejected as duplicate. Fixed translation language for China.
  • FIXED: Changed from GET to POST for Google Translations to support extra long review texts.
  • FIXED: Bug would cause link between InAppPurchase and App to disappear upon restart
  • CHANGED: Rewrote totalling to cache and replace averaging
  • CHANGED: Numerous performance improvements
  • ADDED: Lazy loading for reviews for additional speed improvement on startup
  • ADDED: Transparent 2-stage loading of reviews to speed up opening of review page for an app
  • CHANGED: Made more UI elements opaque to speed up table view drawing
  • ADDED: Financial and Monthly Free download on Import/Export homepage

Generally if you have any issues after applying this update then please go to the settings page and tap “Empty Caches”. This removes all the cached .dat files keeping information for faster access.

Now that I am coding full time I can spend hours and hours on lots of things. I have to literally force myself not to take on too much before releasing a new version. I’ll have to start updating all my other apps, create some new ones and then there are some looming contracts.

Dr. Touch #006 – "And the Winner is…"

Appsfire Award 2009 Winners announced and the problem with fake reviews.

Subscribe to the Podcast in iTunes

My script (aka “Show Notes”) after the fold below.

Read more

iTunes Release Dates

Mingleboy asked Apple via E-Mail:

“Why does my updated app not appear amongst the new apps even though I changed the release date on iTunes Connect?”

We all remember that previously it was possible to hop to the first pages of iTunes by changing this date. And of course this “feature” was exploited quite a bit by developers hoping to achieve additional attention for their apps and thus additional sales.

Apple recently fixed this to match what they originally intended, it appears now that it was a bug in the system anyway that Apple willingly ignored for some time until the gaming of release dates overboarded. I reported about this change in Episode 1 of the Dr. Touch Podcast.

Read more

Dr. Touch #005 – "Advent Calendars"

Don’t forget to open all those windows on those app advent calendars.

Subscribe to the Podcast in iTunes

My script (aka “Show Notes”) after the fold below.

Read more

Dr. Touch #004 – "Revolution"

Our favorite company gives in, it’s revolutionary!

Subscribe to the Podcast in iTunes

My script (aka “Show Notes”) after the fold below.

Read more

MyAppSales 1.0.13 "Mo' Money"

This new release is about fully integrating In App Purchases (IAP) into MyAppSales. Until now I did not need for IAPs to be displayed correctly because none of my apps have them. But my friends over at Crowded Road kept insisting that this is a key feature, so I invested some time to give IAP the special treatment.

Changes:

  • FIXED: Prevent app from saving incomplete reports without a date. This would cause a crash on subsequent starts of the app. There are also additional measures to prevent loading such a report should it be present in the database.
  • FIXED: Added missing country FI as identifier for Europe region of financial reports.
  • FIXED: Added missing country CO as identifier for USA region.
  • FIXED: Correct spelling of country Vietnam. This would cause a financial report with this country in the first line to be detected as “rest of world”.
  • CHANGED: If you have reports from more than one app grouping (aka Apple account) then reports for those no longer show the apps of other groupings.
  • CHANGED: Apps and IAPs are now child classes of Product to allow for polymorphism.
  • ADDED: IAP Products are now kept in a separate table from apps
  • ADDED: IAP support on the overview and country detail report views
  • ADDED: IAP support for export via built-in web server

The other reporting apps I had a look at tread IAPs just like regular apps, because at first glance they look the same in Apple’s reports. They have an apple identifier, but it’s not valid to open iTunes with it. To tell IAPs apart from apps you have to look for the IA1 transaction code and the filled in parent code. In the table the transaction is represented as 101 because it needs to be numeric.

Personally I am opposed to showing IAPs at the same level as apps and therefore MyAppSales shows you IAPs as part of the total royalties and average daily sales on the app page and also integrates it into the report views. If you don’t have IAPs you will not notice any difference in the UI.

Still you are encouraged to update your working copy to the latest version in the repo’s trunk or the release-1.0.13 tag because of the multitude of small fixes contained and for IAPs to be handled correctly should you ever have any on any report.

Bug reports or feature requests please add to my bug tracker.