In-App Advertising

January 7th, 2010

Over the Christmas period, Matt Martel decided to offer free advertising within his reMovem app to other indie iPhone developers. I took him up on this offer for my BeerMap application. I want to thank Matt for such an excellent idea and I want to share with everyone the sales figures which I saw.

So below is a table and graph of the sales data for 7 days prior to the promotion, the 7 days during the promotion and the 7 days following the promotion. You can clearly see that the promotion had a big impact on sales. Interestingly, there is still an increase in sales following the promotion which is likely to be due to the increased rank of the app following the strong sales during the promotion.

BeerMap In-App Promotion Stats

Thanks again Matt!

So I released an update to BeerMap a couple of weeks ago. This was version 2.0 which was going to be a huge release which I really wanted to happen before Christmas and that’s why I spent 2 months perfecting it and released it with 3 weeks to go until Christmas which I assumed would be fine. Sadly, I was wrong.

Apple first started reviewing the app a week ago, after just 5 days of being “waiting for review” (I can tell this from server logs because the app is designed around a web services – http://www.ibeermap.co.uk/). It then took over a week for Apple to come back and tell me that the app had been rejected because they thought the app needed a 17+ rating. It currently is in the app store at a 12+ rating for “mild alcohol references” but they thought it needed “strong alcohol references”.

So, my questions are thus:

  1. Why did they feel the need for the sudden change in rating?
  2. Why did I have to RESUBMIT the app even though the problem was with the rating and not the actual app

I started getting this strange message when compiling for my iPhone:

ldr 12-bit displacement out of range

Eventually I found that quitting XCode, deleting the build folder in the project then reopening XCode and re-building made everything work again.

Just putting here in case anyone else has similar issues!

iPhone DNS Servers

November 17th, 2009

I have been bashing my head against the fact that on the iPhone you seemingly cannot access /etc/resolv.conf, or use functions from the Mac such as SCDynamicStore stuff. I have seen many people asking this question, a few related to the same package I was trying to use – ares.

Eventually I managed to find a fix which uses the libresolv to find the DNS servers. This seems to work just fine and I have shown the patch to ares_init.c below for reference.

#if TARGET_OS_IPHONE
#include <resolv.h>
#endif

...

#if TARGET_OS_IPHONE
// XXX: On the iPhone we need to get the DNS servers using resolv.h magic
if ((_res.options & RES_INIT) == 0) res_init();
channel->nservers = _res.nscount;
channel->servers = malloc(channel->nservers * sizeof(struct server_state));
memset(channel->servers, '\0', channel->nservers * sizeof(struct server_state));

int i;
for (i = 0; i < channel->nservers; i++)
{
    memcpy(&channel->servers[i].addr, &_res.nsaddr_list[i].sin_addr, sizeof(struct in_addr));
}
#endif

[As per most of my posts these days, this is just a brain dump. I'll try to pad it out as soon as possible]

3rd party libraries used by iPhone applications are required to be linked statically. In order to build such a library for the device and simulator you need to set up your environment such that it will cross compile for the two different environments. This is as simple as using the following set of ‘exports’ as defined below.

Device:

export DEVROOT=/Developer/Platforms/iPhoneOS.platform/Developer
export SDKROOT=$DEVROOT/SDKs/iPhoneOS3.0.sdk
export CC=$DEVROOT/usr/bin/gcc
export LD=$DEVROOT/usr/bin/ld
export CPP=$DEVROOT/usr/bin/cpp
export CXX=$DEVROOT/usr/bin/g++
export AR=$DEVROOT/usr/bin/ar
export AS=$DEVROOT/usr/bin/as
export NM=$DEVROOT/usr/bin/nm
export CXXCPP=$DEVROOT/usr/bin/cpp
export RANLIB=$DEVROOT/usr/bin/ranlib
export LDFLAGS="-arch armv6 -pipe -Os -gdwarf-2 -no-cpp-precomp -isysroot $SDKROOT -L~$SDKROOT/usr/lib"
export CFLAGS="-arch armv6 -pipe -Os -gdwarf-2 -no-cpp-precomp -isysroot $SDKROOT -I~$SDKROOT/usr/include"
export CXXFLAGS="-arch armv6 -pipe -Os -gdwarf-2 -no-cpp-precomp -isysroot $SDKROOT -I~$SDKROOT/usr/include0"

Simulator:

export DEVROOT=/Developer/Platforms/iPhoneSimulator.platform/Developer
export SDKROOT=$DEVROOT/SDKs/iPhoneSimulator3.0.sdk
export CC=$DEVROOT/usr/bin/gcc
export LD=$DEVROOT/usr/bin/ld
export CPP=$DEVROOT/usr/bin/cpp
export CXX=$DEVROOT/usr/bin/g++
export AR=$DEVROOT/usr/bin/ar
export AS=$DEVROOT/usr/bin/as
export NM=$DEVROOT/usr/bin/nm
export CXXCPP=$DEVROOT/usr/bin/cpp
export RANLIB=$DEVROOT/usr/bin/ranlib
export LDFLAGS="-arch i386 -pipe -Os -gdwarf-2 -no-cpp-precomp -isysroot $SDKROOT -L~$SDKROOT/usr/lib"
export CFLAGS="-arch i386 -pipe -Os -gdwarf-2 -no-cpp-precomp -isysroot $SDKROOT -I~$SDKROOT/usr/include"
export CXXFLAGS="-arch i386 -pipe -Os -gdwarf-2 -no-cpp-precomp -isysroot $SDKROOT -I~$SDKROOT/usr/include"

Once you have set the environment, you just need to use ‘make’ to build the library. If the library is using autoconf, then you will need to use the following ‘./configure’ options:

Device:

./configure --host=arm-apple-darwin9 --prefix=~$SDKROOT --enable-shared=no

Simulator:

./configure --host=i386-apple-darwin --prefix=~$SDKROOT --enable-shared=no

Then just use ‘make’ and ‘make install’ to build the library! It really is as easy as that :-D .

[Other libraries may require other configure options, but I can't cover them all here as they are often different]

Compiling Boost for the iPhone

November 10th, 2009

For a recent project I’ve had to compile the Boost C++ library for the iPhone. Much of the Boost library is header files so they are fine as nothing needs to be done, they just get copied into place, but the bits which do need compiling are a bit trickier. So I thought I’d share my experiences here.

First you need to download Boost (I went for version 1.40) from http://www.boost.org. Then you need to edit some of the Boost.Jam configuration. This involves creating a user-config.jam file in your home directory like so:

~/user-config.jam:
using darwin : 4.2.1~iphone
   : /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 -arch armv6
   : <striper>
   : <architecture>arm <target-os>iphone <macosx-version>iphone-3.0
   ;

using darwin : 4.2.1~iphonesim
   : /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc-4.2 -arch i386
   : <striper>
   : <architecture>x86 <target-os>iphone <macosx-version>iphonesim-3.0
   ;

Then edit tools/build/v2/tools/darwin.jam and add in the following under the macosx-versions variable:

.macosx-versions =
    10.6 10.5 10.4 10.3 10.2 10.1
    iphone-3.1 iphonesim-3.1
    iphone-3.0 iphonesim-3.0
    iphone-2.3 iphonesim-2.3
    iphone-2.2 iphonesim-2.2
    iphone-2.1 iphonesim-2.1
    iphone-2.0 iphonesim-2.0
    iphone-1.x
    ;

Then, you need to use the following lines to build Boost for iPhoneOS and iPhoneSimulator respectively:

./bjam --prefix=~/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/usr toolset=darwin architecture=arm target-os=iphone macosx-version=iphone-3.0 define=_LITTLE_ENDIAN link=static include=/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/usr/include/c++/4.2.1/armv6-apple-darwin9 install
./bjam --prefix=~/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/usr toolset=darwin architecture=x86 target-os=iphone macosx-version=iphonesim-3.0 link=static include=/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/usr/include/c++/4.2.1/i686-apple-darwin9 install

It’s worth noting that at this stage everything will compile for the simulator but not for the device. This is because the device is missing two header files – ‘bzlib.h’ and ‘crt_externs.h’. To make it compile for the device simply copy these files from ‘/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/usr/include/’ into your Boost folder and then everything should compile fine. I have no idea why Apple have omitted these header files from the device. The libraries are there, just the header files missing. I’ve created a bug on Radar for this, so please also do the same if you encounter this problem such that Apple will listen and include them.

That installs the files in ‘~/Developer/Platforms/iPhone(OS|Simulator).platform/Developer/SDKs/iPhone(OS|Simulator)3.0.sdk/usr’ which was where I wanted mine to go, but feel free to change that to wherever you want the libraries to end up. I did it this way because I created a custom SDK and then include that from iPhone projects within XCode.

I’ll try to update this with more information, this is merely a brain dump at the moment but hopefully it will be helpful for other people.

In-app Purchase on Free Apps

October 16th, 2009

Apple have announced the ability to allow in-app purchase on free apps. This is an interesting feature in my opinion. It will allow for some annoying “lite” versions which hide paid-for features which you have to pay to unlock, but also it will allow developers to leverage some interesting sales techniques.

This is one of the most exciting things I have seen Apple do over the past couple of months!

Mark my word: Tablet, May, 2010

LiDG 7th October 2009

October 8th, 2009

Yesterday, there was the monthly LiDG (London iPhone Developer Group) meet-up in the Apple Store, Regent Street. This month Ian Thain decided to allow developers to present for 1 minute (strictly!) about their apps. I chose to give a quick talk about BeerMap, giving the people there a quick run down on why they should download BeerMap and review some beers with it!

It seemed to get good feedback and along side other apps such as CurryFinder it was probably one of the most fun apps being showcased. I really enjoyed telling people about it and I hope that people will have downloaded and started using the app from seeing my presentation!

Below is a little photo of me presenting!
Matt Presenting at LiDG 7th October 2009

I found an article by Andrew Nusca on ZDNet which caught my eye. He gives 5 points as to why Android will beat other smartphones. I’d like to comment on them:

* Google backs Android, a major pipeline for its cloud services.
Yes, true, but Apple backs the iPhone and clearly has cloudy things in the pipeline with it’s building of a new billion dollar data centre.

* Android is improving rapidly. The Cupcake 1.5 release was well-received, and Donut 1.6 has already been sent over the air to handset owners.
iPhone OS is improving all the time as well. Granted Android is faster, but for developers I think it’s great how Apple release iPhone OS. It means you have time to get ready for each release to make sure all apps work properly on each version.

* Android is open, making it easier to quickly gain developers’ support.
The iPhone SDK is free to download and only £59 to become a member of the full developer program. It’s really not that much of a barrier.

* Android will run on phones from several manufacturers, which will help it quickly spread through the marketplace. HTC, Motorola and Samsung are already supporting handsets.
This is a bad thing in my opinion. I absolutely love the fact that with the iPhone you know exactly what devices the app will run on, and you know every exact specification. Only if the hardware manufacturer is the SDK provider, can this happen 100%.

* Android combines the best of what’s out there. It’s open, but it offers iPhone-like menus and apps, with Windows Mobile-esque icons, with Palm Pre-like multitasking. There’s another arms race afoot — the battle among Android handset makers as to which company can squeeze the most out of the OS.
Is that a good thing to mix-and-match? I prefer having a rock solid, stable OS, built by one of the best software companies in the world. Furthermore, they build the hardware as well so they know how to eek every last bit of power out of the hardware to provide software developers with one of the best platforms to develop for.

I Like Competition!

September 9th, 2009

Every now and then I check for the competition of Subnet Calc and Subnet Calc Pro on iTunes. Today I found a couple of new ones called IPSubnet and ITcalc4. Now, I don’t want to be rude but these just don’t seem as easy to use as Subnet Calc and what’s more, they both cost 59p / 99c whereas Subnet Calc is FREE! Granted, Subnet Calc Pro costs some money but I am hoping to always have the free version there for people who just want a quick and easy subnet calculator on their device.

Comments are welcomed for any points you have to make about Subnet Calc or any of its competitors.