BuySellAds.com

My book Barcodes with iOS 7 is nearing completion. Buy it now to get early access!
Our DNA is written in Objective-C
Jump

iPhone 4 Tripod Mount Shootout

UPDATE: I also reviewed the glif and compared it with these mounts.

If you’re like me then you justified getting an iPhone 4 (on top of the original 2G, 3G and 3GS) by telling your wife “honey, this has an HD camcorder BUILT IN. By getting this we actually SAVE the money for an extra device.” And then on the second or third video you’re shooting you’ll find that you have the hands of a programmer and not of a surgeon. Meaning that it is next to impossible holding the iPhone perfectly steady.

Yet once more we see that technology has advanced to a level where it is no longer the limiting factor, but instead the human body is. For all intents and purposes of my iPhone business I deem the quality of the iPhone 4 video recorder more than sufficient. If only there was something that would help me steady my aim and frame. Well, there is, because this problem is one that photographers and videographers have been having for a long time. And most of the solutions revolve around contraptions that allow you to levitate your lens in a fixed distance from the floor.

I am of course talking about the tripod. You might remember from geometry that any surface can be described by 3 points. Tripods define a point by three feet. The point where you can mount a camera usually has two or three degrees of freedom which you an restrict by tightening screws. One or two of these screws might be attached to a handle that would allow you to move the tripod head around and adjust the tightness of one scree by turning your wrist.

I shopped around for a 3-way tripod to mount my iPhone 4 on and ended picking the Cullmann Nanomax 250 which is a sturdy but extremely lightweight tripod that almost fits into my backback. Because it is made out of aluminum it weighs only 2.3 lbs (1 kg). So it’s ideally light and compact to work for a blogging developer like myself. Cullmann in Germany grants you 10 year warranty on the tripod if you register on their website.

But this article is not about my choice of tripod. Once you got one you are presented with the challenge to somehow mount your pretty iPhone on it. That’s where special cam mounts are necessary. I asked around on Twitter and two options were recommended to me. I purchased both and now I’m going to compare them so that you don’t have to.

Read more

NavigationController from NIB produces sticky gray empty status bar on rotation

I’ve decided that I’ll share my bug reports on my blog from now on as well. Usually you’ll have to make a small demo project to demonstrate the bug to Apple’s engineers and then they are the only ones to see my work. What a waste.

I still believe that Apple’s Bug Reporting system should be open for everybody, but since Apple is still run like a small startup they feel that it helps them conserve more resources to have it closed. That’s why there is Open Radar which somebody put on Google App Engine.

So, here’s my full bug report plus the demo project and screen shot. See if you can reproduce it and find a workaround.


NavigationController from NIB produces sticky gray empty status bar on rotation

16-Aug-2010 06:40 PM Oliver Drobnik KG:
Summary:

If you load a navigation controller from MainWindow.xib, but add the first view controller in appDidFinishLaunching, then there is a problem on rotation. A gray empty status bar appears underneath the regular status bar which cannot be eliminated.

Steps to Reproduce:

  • Create a Navigation based project.
  • Set status bar to be initially hidden.
  • Set navigation controller to want full screen and have nav bar hidden
  • Implement a tap method in the view controller to hide and show the status bar
  • Move the view controller outside of the navigation controller in the IB
  • Add a line to app delegate to push the now separate view controller onto the navigation controller.
  • Start the app, rotate once sideways with shown status bar
  • tap to hide the status bar

Expected Results:

No extra gray status bar.

Actual Results:

A sticky gray status bar appears underneath the disappearing regular status bar.

I’m attaching a project to demonstrate the behavior. Plus a screenshot.

The behavior is inconsistent with creating a navigation controller in code. There no extra status bar appears.


Discussion

I filed this bug report on Open Radar as well. Here’s the Project file I’m referencing: StatusBarBug.zip

To see the bug for yourself launch the demo project in iPad Simulator. Tap the screen to show the black status bar. Then rotate the simulator once. Tap the screen again to hide the status bar. Behind it this gray bar appears.

This is how the screen looks like with the extraneous status bar showing.

Iif you set the navigation controller’s root view controller already in the NIB (as it’s usually the case) then this behavior does not occur. So for this demo I moved the view controller outside of the navigation controller.

If you don’t instantiate the navigation controller via a NIB file, but instead put the following code into the applicationDidFinishLaunching, then you will not see this extra bar.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
	// could also initWithRootViewController, same effect
 
 	navController = [[UINavigationController alloc] init];
	navController.wantsFullScreenLayout = YES;
	navController.navigationBar.hidden = YES;
 
	[navController pushViewController:viewController animated:NO];
 
	[window addSubview:navController.view];
	[window makeKeyAndVisible];
 
	return YES;
}

This leads me to the conclusion that something funny is happening when getting your navigation controller from a xib (without root view controller set) versus instantiating it in code. Which prompted me to file this bug. If you find that it is actually something that I am doing wrong here, please let me know.

Tap&Hold for TableView Cells, Then and Now

It was before SDK 3.2 that I developed a technique to add tap-and-hold interactivity to your tableview cells. In this article I’ll demonstrate the old technique, which still works, and contrast it with how much easier it has become if you can target iOS 3.2 and above.

First the “old way”. It needs to customize touch handling for the tableview cells themselves, which means you have to subclass UITableViewCell.

Read more

MyAppSales for Partners

A user of MyAppSales approached me and asked for the possibility to pre-configure the app such that he could give it to a partner of his. The goal was twofold:

  1. Pre-configure the account for iTunes Connect such that you don’t have to give your credentials to your partner
  2. Filter sales reports such that only the apps come through that the partner is receiving a share of sales for

… and all of this without impacting the other features like review downloading.

Since I have such a partner myself for which I’m now publishing 3 apps, I sat down and – after fighting with Xcode over a second target – added a couple of lines to the MyAppSales trunk to enable the “Partner Version”.

In the PCH file you enable and configure this special version by removing the // in front of the first define. Then you need to specifying your ITC credentials and an NSSet of Apple App Identifiers.

// to enable the partner version, re-enable the following define and fill in the three values below
//#define PARTNERVERSION
 
#define PARTNERVERSION_ITC_LOGIN @"account@server.com"
#define PARTNERVERSION_ITC_PASSWORD @"SECRETPASSWORD"
#define PARTNERVERSION_FILTER_APPS_SET [NSSet setWithObjects:@"335519920", @"329678407", @"374457741", nil]

I’ve added a filter for the specified PARTNERVERSION_FILTER_APPS_SET in two places to ignore all lines on sales report where neither the Apple Identifier nor the Parent ID is in this list. Since the app never sees any apps outside of this filter those also won’t pop up on the apps page.

For the preconfigured account, the app adds this ITC account if there are no accounts defined. So if your partner were to remove this account accidentally it would be configured once more on next app start.

All you need to do after configuring and building a release version is to zip and ship the app and provisioning profile to your partner. Easy enough?

DTBannerManager

You have AdMob ads in your apps? Wondering if you could make a bit more money if you also had iAds were available?

DTBannerManager solves this problem for you. It allows for easily adding both networks to your code. Under iOS 4 it will first try to get an iAd because those also pay for just being displayed. If none is available then it automatically switches to AdMob, so your banner space is never wasted. It also features elegant sliding in and out of the banners and is able to display ad banners even over a tab bar controller, so they are always visible for maximum effect.

You might argue that there are free ad networks out there who promise to do exactly this for free. So why would you want to get this component from me. Well, from you you get full source code and you see exactly what is happening. Also there is no server-side ad mediation happening that might get you in trouble with Apple. I believe that as developer you don’t want to involve too many additional parties and introduce too many external dependencies. With DTBannerManager you continue own all parts of your code and have full transparency.

What’s also great is that you can use this component will work on both 3.x and 4.x iOS Versions. This way you can target the broadest possible audience with reaping the benefits of iAds if available.

Adding advertising is exceedingly simple:

#ifdef FREEVERSION
	[[DTBannerManager sharedManager] addAdsToViewController:tabBarController];
#endif

Then you can just subscribe to the notifications to adjust the viewing area of your view controllers.

DTBannerManager is proving it’s worth already in GeoCorder [FREE]. There was a bug preventing “clicking through” in Ads that I have since fixed. The component is available through the Dr. Touch’s Parts Store.

CGRect Tricks

CGRect might just be one of the most often used structures that you have in your fingers when coding for iPhone. View frames and bounds are something that you touch way more often than dealing with CGSize or CGPoint values.

So it pays to know about all the nifty utilities that Apple provides for you to make your life easier.

Read more

GeoCorder 1.1.0

Some time ago I got approached by a corporate customer who was looking for a solution to have his vehicles report their location to his server. Previously he had been using Nokia phones and now he was looking to switch to iPhones. So I built a quick app for him, but due to lack of multitasking in iOS 3 it had limited use. But then Apple surprised us with backgrounding for location apps and suddenly make apps like GeoCorder all the more useful.

But I did not think that this mini tracking app by itself would make a good addition to the app store, so I insisted of merging this functionality into GeoCorder. So now GeoCorder can record GPX tracks for photo tagging or viewing in Google Earth and can also ping your server with a customizable HTTP GET.

  • Background Recording on iOS 4
  • UI improvements
  • Completely rewritten backend with CoreData engine
  • FREE Version: iAds on iOS 4 Devices with AdMob fallback
  • User Guide and Support
  • Map View centering on current Location
  • Tracker Mode to ping corporate server with location updates

For the UI you might notice that I moved the recording controls into the navigation bar. Also this is now using a tab bar controller to switch between multiple views with differing functionality. I switched the tracks view and the recording view because for a recording app the recording screen obviously is the more important view.

Once I started to think about the functionality of this app I suddenly had my head fill will lots of additional things, most of which did not make the cut for what is supposed to be a minor upgrade that turned into a 4 day project. For example I had considered adding Google Latitude updating as a Tracking choice. But 1.1.0 is meant to give my customer (and other people with similar logistics use cases) a tool which he can easily install through the app store.

The problem with those many ideas is that nobody is paying for their implementation. On both the full and the free version (ads) I’m making like 10 Dollars a week. Only if I see a dramatic uptake in downloads I will be able to afford implementing more features. But I’m still interested to hear your thoughts should you be amongst those few people who have a use for this uncomplicated app.

Maybe it helps a bit that I am also targeting iOS 3.x which still is the OS of choice for iPhone 3G. Where I previously had only AdMob ads, I have now also iAds on iOS 4 devices with AdMob being the fallback. I’ll report on how that goes.

I just submitted the app to Apple for approval. I tested orders of magnitude more than before and eliminated all bugs that I could find to make this a really high quality release.

Update Aug 6th: The update has been approved. What’s a first is that the review team approved the update first and later wrote a mail to me asking to add a battery disclaimer to the iTunes description. Apparently all apps using background GPS are required to have this in the description:

“Continued use of GPS running in the background can dramatically decrease battery life.”

So I added it. Much obliged!

Update: I found two bugs in the free version for which I just submitted update 1.1.1: Ads could not be tapped on and I had forgotten to include background location support.

Apple Store Down

Update: of course I meant to say that the “Apple Store” is down, not the “App Store”.

Every time the App Store Apple Store goes down the world gasps with excitement. New Macs? Any hardware refreshes?

Here’s a script that you can execute at the command line that will notify you as soon as the store is back up. I found this script here and modified it to use the built-in say command instead of growlnotify which I did not have.

#! /bin/bash
 
until [ 1 -eq 2 ]
do
        echo -n "Checking ..."
        MYVAR=`curl -s http://store.apple.com/us | grep backsoon | grep australia`
        if [ "$MYVAR" == "" ]
        then
                if [ ! -f "/tmp/storeup.txt" ];
                then
                        echo "UP!"
                        say "The Store is up!"
                        echo "1" > /tmp/storeup.txt
                        exit
                fi
        else
                echo "down"
        fi
 
        sleep 10
done

To use it just paste this script into a file storecheck, make it executable and run it in terminal. This runs an endless loop and as soon as the store is up will say “The Store is up!”.

Cells with Switch

When I revisited the settings screen on MyAppSales to add a switch it turned my stomach how I would have added it over a year ago versus to the way I’m doing it now.

The Old Way

Consider the following snipped just to get a similar nausea so that you can appreciate what I am going to show you afterwards. That’s from a random switch in cellForRowAtIndexPath.

NSString *CellIdentifier = @"ServerSectionSwitch";
 
SwitchCell *cell = (SwitchCell *)[tableView dequeueReusableCellWithIdentifier:
		CellIdentifier];
if (cell == nil)
{
	cell = [[[SwitchCell alloc] initWithFrame:CGRectZero reuseIdentifier:
		CellIdentifier] autorelease];
}
 
cell.titleLabel.text = @"Enable on WLAN";
ASiSTAppDelegate *appDelegate = (ASiSTAppDelegate *)[[UIApplication sharedApplication]
		delegate];
 
cell.switchCtl.on = appDelegate.serverIsRunning;
[cell.switchCtl addTarget:appDelegate action:@selector(startStopServer:)
			forControlEvents:UIControlEventValueChanged];
return cell;

So obviously I had created a custom tableview cell, so let’s glance at that as well.

Read more

MyAppSales 1.0.16

Apple changed two column headings on the financial reports because apparently the June reports are the first ones which will also show eBook publishers their revenues.

  • “Artist/Show/Developer” became “Artist/Show/Developer/Author”
  • “Label/Studio/Network/Developer” became “Label/Studio/Network/Developer/Publisher”

There where quite a few hot fixes that I had to put into MyAppSales and also if you look at the code you’ll see that it’s in the middle of being migrated to CoreData. The latter is necessary because the current method of caching everything is really ugly code whereas CoreData will permit me to make the app perform way better and it only fetches data I truly need.

Unfortunately (or fortunately depending on how you look at it) I’m very busy with a major project for the last few months, so I cannot really muster the time right now to carry through this migration. But because this is a point of stability in MyAppSale’s live that I can publish it as a new version. Lots of people where continuing to use the previous “released” version because for some reason they feared that the “2.0 BETA” in the Subversion trunk might be unstable. When in reality it aways was the code I’ve been using on my iPhone.

Speaking of iPhone 4, you still need to build it with SDK 3.2 until further notice for exactly the reason I mentioned above: ugly caching. It works fine on my iPhone 4.

Here are some goodies that I also hacked into 1.0.16:

  • Ability to remove individual reports. For example if something goes wrong during download.
  • You can opt to show a report sum on the overview pages. This is slower because for it the app needs to fetch the sales data, so it will impact scrolling. But if you don’t scroll much then its a useful number to see at a glance.
  • I’m now using the standard currency formatter for all amounts

Please update your copy from the repository as usual.